简体   繁体   English

Visual Studio C ++ DLL库在Qt应用程序中崩溃

[英]Visual Studio C++ dll library crashes in Qt application

I have a problem sharing "std::string" data between MS Visual C++ DLL library and Qt program. 我在MS Visual C ++ DLL库和Qt程序之间共享“std :: string”数据时遇到问题。

What I have are: 我有的是:

  • DLL library written in Visual C++ 2010 Express, which exports one method: 用Visual C ++ 2010 Express编写的DLL库,它导出一个方法:

     extern "C" __declspec(dllexport) int Init(ITest* commandTest); 
  • Abstract interface "ITest" and a class implementing it: 抽象界面“ITest”和实现它的类:

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

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

In DLL's "Init" a "CTest::getVersion()" method is called. 在DLL的“Init”中,调用“CTest :: getVersion()”方法。 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. 我希望它会填充“&version”字符串。当我用新字符串填充“&version”时,我得到的是崩溃。

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. http://qt-project.org/downloads下载了“Qt libraries 4.8.3 for Windows(VS 2010,235 MB)”,安装它并在QtCreator的项目设置中选择它。

  • in QtCreator switched from MinGW toolchain to the one installed with MS Visual Studio 2010 Express. 在QtCreator中从MinGW工具链切换到使用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. 我认为它将克服这个问题,因为我使用了VS 2010编译的Qt库,Qt GUI也用VS C ++工具链编译。 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!! 在Visual Studio中创建Win32控制台应用程序,通过LoadLibrary加载我的DLL,使用“Init”方法,就像我在Qt GUI中一样...并且它工作!

Small observation 小观察

In "CTest::getVersion()" I am printing this "version" string passed by reference to the console. 在“CTest :: getVersion()”中,我打印通过引用传递给控制台的“版本”字符串。 When using VS C++ console app as a host it is printed out correctly. 使用VS C ++控制台应用程序作为主机时,它将正确打印出来。 When using Qt app - the "version" string is printed with some garbage around (eg ┌►☻qwerty27) 当使用Qt应用程序时 - “版本”字符串打印出一些垃圾(例如┌►☻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. 这让我觉得Qt app和我的DLL的ABI仍然不兼容,即使使用上面提到的Qt VS 2010库。

Questions: 问题:

  • Is using Qt libraries for Windows (VS 2010) and Visual Studio toolchain not enough to overcome ABI compatibility issues? 是否使用Windows的Qt库(VS 2010)和Visual Studio工具链不足以克服ABI兼容性问题?
  • Does it mean I should compile the Qt framework on my own? 这是否意味着我应该自己编译Qt框架?
  • Please help - any ideas are welcome... 请帮忙 - 欢迎任何想法......

In a project I had a situation much like yours, two DLLs, same compiler (VC++ 2010). 在一个项目中,我的情况很像你的,两个DLL,相同的编译器(VC ++ 2010)。 I was passing std::string from one to the other and getting a lot of crashes. 我正在将std :: string从一个传递到另一个并且发生了很多崩溃。

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). 问题是一个DLL使用多线程调试DLL(/ MDd)编译,另一个DLL使用多线程调试(/ MTd),这导致两个DLL(崩溃)之间的二进制不兼容。 Also the versions have to match, either use DEBUG or RELEASE for both DLLs. 此外,版本必须匹配,对两个DLL使用DEBUG或RELEASE。

Looking at your project, both DLLs seem to be using Multi-threaded Debug DLL (/MDd) . 看看你的项目,两个DLL似乎都在使用多线程调试DLL(/ MDd) this means both are using MSVCP100D.dll . 这意味着两者都在使用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 这没关系,唯一的问题是来自QT网站的qt的VC ++版本是在RELEASE模式下编译的,并且正在使用MSVCP100.DLL

My recommendation is to change your runtime library to Multi-threaded DLL (/MD) for your DEBUG configuration. 我的建议是将您的运行时库更改为DEBUG配置的多线程DLL(/ MD)

My second recommendation is to follow Rebert's advice and use char* instead of std::string. 我的第二个建议是遵循Rebert的建议并使用char *而不是std :: string。 char* will be compatible no matter what. char *无论如何都会兼容。

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). 您还可以使用多线程调试DLL(/ MDd)重新编译QT,并使用该版本的QT进行DEBUG配置(但这似乎很有用)。

Nominally I would not venture into passing complex data (out of my control, codewise) between an application and a DLL. 名义上我不想冒险在应用程序和DLL之间传递复杂的数据(在我的控制之外,代码方面)。 I would resort to only pass POD structures, ie I would change the interface to this instead: 我会求助只传递POD结构,即我将接口更改为:

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

Makes life a lot easier ;) 让生活更轻松;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM