Visual Studio C++ dll library crashes in Qt applic

2019-04-05 18:23发布

问题:

I have a problem sharing "std::string" data between MS Visual C++ DLL library and Qt program.

What I have are:

  • DLL library written in Visual C++ 2010 Express, which exports one method:

    extern "C" __declspec(dllexport) int Init(ITest* commandTest);
    
  • Abstract interface "ITest" and a class implementing it:

    class CTest: public ITest
    {
    public:
        CTest();
        virtual ~CTest();
        virtual void getVersion(std::string & version) const;
    };
    
  • Qt GUI application that needs to:

    * load the DLL dynamically
    * instantiate CTest and pass it to exported Init method.
    

In DLL's "Init" a "CTest::getVersion()" method is called. I'd expect it would get the "&version" string filled in. What I get instead are crashes on the line when I fill "&version" with new string.

What I already did:

  • downloaded "Qt libraries 4.8.3 for Windows (VS 2010, 235 MB)" from http://qt-project.org/downloads, installed it and selected it in QtCreator's project settings.

  • in QtCreator switched from MinGW toolchain to the one installed with MS Visual Studio 2010 Express.

    I thought that it will overcome the problem , because I used Qt libraries compiled with VS 2010 and the Qt GUI was also compiled with VS C++ toolchain then. Unfortunately the problem was not gone, so I tried the last step:

  • created Win32 Console application in Visual Studio, loaded my DLL via LoadLibrary, used "Init" method the same way as I did in Qt GUI... and it worked!!

Small observation

In "CTest::getVersion()" I am printing this "version" string passed by reference to the console. When using VS C++ console app as a host it is printed out correctly. When using Qt app - the "version" string is printed with some garbage around (e.g. ┌►☻qwerty27)

This makes me think that ABI of Qt app and my DLL is still incompatible, even when using Qt VS 2010 libraries mentioned above.

Questions:

  • Is using Qt libraries for Windows (VS 2010) and Visual Studio toolchain not enough to overcome ABI compatibility issues?
  • Does it mean I should compile the Qt framework on my own?
  • Please help - any ideas are welcome...

回答1:

In a project I had a situation much like yours, two DLLs, same compiler (VC++ 2010). I was passing std::string from one to the other and getting a lot of crashes.

The problem was one DLL was compiled with Multi-threaded Debug DLL (/MDd) and the other with Multi-threaded Debug (/MTd) this caused binary incompatibility between the two DLLs (crashes). Also the versions have to match, either use DEBUG or RELEASE for both DLLs.

Looking at your project, both DLLs seem to be using Multi-threaded Debug DLL (/MDd). this means both are using MSVCP100D.dll. This is ok, the only problem is that the VC++ version of qt from the QT website is compiled in RELEASE mode and is using MSVCP100.DLL

My recommendation is to change your runtime library to Multi-threaded DLL (/MD) for your DEBUG configuration.

My second recommendation is to follow Rebert's advice and use char* instead of std::string. char* will be compatible no matter what.

You can also recompile QT with Multi-threaded Debug DLL (/MDd) and use that version of QT for your DEBUG configuration (but this seems like to much work).



回答2:

Nominally I would not venture into passing complex data (out of my control, codewise) between an application and a DLL. I would resort to only pass POD structures, i.e. I would change the interface to this instead:

class CTest: public ITest
{
public:
    CTest();
    virtual ~CTest();
    virtual void getVersion(char* versionBuffer, unsigned length) const;
};

Makes life a lot easier ;)