我在MS Visual C ++ DLL库和Qt程序之间共享“std :: string”数据时遇到问题。
用Visual C ++ 2010 Express编写的DLL库,它导出一个方法:
extern "C" __declspec(dllexport) int Init(ITest* commandTest);
抽象界面“ITest”和实现它的类:
class CTest: public ITest
{
public:
CTest();
virtual ~CTest();
virtual void getVersion(std::string & version) const;
};
需要的Qt GUI应用程序:
* load the DLL dynamically
* instantiate CTest and pass it to exported Init method.
在DLL的“Init”中调用“CTest :: getVersion()”方法。我希望它会填充“& version”字符串。当我用新字符串填充“& version”时,我得到的是崩溃线。
从http://qt-project.org/downloads下载了“Qt libraries 4.8.3 for Windows(VS 2010,235 MB)”,安装它并在QtCreator的项目设置中选择它。
从MinGW工具链切换到使用MS Visual Studio 2010 Express安装的工具链。
我认为它会克服这个问题,因为我使用了VS 2010编译的Qt库,Qt GUI也是用VS C ++工具链编译的。不幸的是问题没有消失,所以我尝试了最后一步:
在Visual Studio中创建了Win32控制台应用程序,通过LoadLibrary加载了我的DLL,使用“Init”方法,就像我在Qt GUI中一样......并且它有效!!
在“CTest :: getVersion()”中我打印通过引用传递给控制台的“版本”字符串。使用VS C ++控制台应用程序作为主机时,它将正确打印出来。当使用Qt应用程序时 - “版本”字符串打印出一些垃圾(例如┌►☻qwerty27)
这让我觉得Qt app和我的DLL的ABI仍然不兼容,即使使用上面提到的Qt VS 2010库。
答案 0 :(得分:1)
在一个项目中,我的情况很像你的,两个DLL,相同的编译器(VC ++ 2010)。我正在将std :: string从一个传递到另一个并且遇到很多崩溃。
问题是一个DLL是用多线程调试DLL(/ MDd)编译的,另一个是用多线程调试(/ MTd)导致二进制不兼容两个DLL之间(崩溃)。 此外,版本必须匹配,对两个DLL都使用DEBUG或RELEASE。
查看您的项目,两个DLL似乎都在使用多线程调试DLL(/ MDd)。这意味着两者都在使用 MSVCP100D.dll 。这没关系,唯一的问题是来自QT网站的qt的VC ++版本是在RELEASE模式下编译的并使用 MSVCP100.DLL
我的建议是将您的运行时库更改为DEBUG配置的多线程DLL(/ MD)。
我的第二个建议是遵循Rebert的建议并使用 char * 而不是std :: string。 char * 无论如何都会兼容。
您还可以使用多线程调试DLL(/ MDd)重新编译QT,并使用该版本的QT进行DEBUG配置(但这似乎很有用)。
答案 1 :(得分:0)
名义上我不想冒险在应用程序和DLL之间传递复杂数据(在我的控制之外,代码方面)。我会求助只传递POD结构,即我将接口更改为:
class CTest: public ITest
{
public:
CTest();
virtual ~CTest();
virtual void getVersion(char* versionBuffer, unsigned length) const;
};
让生活更轻松;)