c – 无法跨DLL传递std :: wstring

前端之家收集整理的这篇文章主要介绍了c – 无法跨DLL传递std :: wstring前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在Visual Studio 2010中设置了一个项目,以针对现有的MFC DLL编写单元测试.我正在使用单头单元测试框架,并链接到单元测试项目中的MFC DLL的lib包装器.我正在尝试构造一个在其构造函数中使用std :: wstring的类.这是我的测试的样子:
TEST_CASE("MyProject/MyTest","Do the test.")
{
    MockDbService mockDbService;
    Foobar foo(L"{F00DFACE-Feed-DEAD-BEEF-C0FFeedECADE}",mockDbService);

    foo.loadObject();

    REQUIRE(mockDbService.getMethodInvokeCount("query()") >= 1);
}

Foobar是从被测MFC DLL导出的类.但是,测试框架会报告意外的异常.在将字符串复制到Foobar的构造函数时,我将其跟踪到std :: wstring的复制构造函数. MSVC调试器将源字符串报告为< Bad Ptr>.

我创建了一个虚拟构造函数,Foobar :: Foobar(long num,IDbService& db),所有的值(包括IDbService&)都很好.

MFC DLL和我的单元测试EXE都共享一个属性表,它应该保持编译器标志等效.我正在调试模式下构建并运行测试.任何想法为什么std :: wstring无法复制到DLL?

解决方法

您应该检查EXE和DLL是否与相同的调试CRT(/ MDd编译器选项)动态链接.确保EXE和DLL的其他设置(如_HAS_ITERATOR_DEBUGGING)相同.

(一种捷径可能是在类接口上使用const wchar_t *而不是std :: wstring,只需从构造函数体内的原始指针构建一个std :: wstring).

编辑:您确认CRT不匹配(即使用/ MD构建的EXE与使用/ MDd构建的DLL)是问题所在.事实是,相同的类名std :: wstring意味着调试版本(/ MDd)和发布版本(/ MD)中有两个不同的类.实际上,在调试版本中,类实现中可以有其他机制来帮助调试;这种机制可能会导致效率低下,因此在发布版本中将其删除.因此,debug build的std :: wstring的内部结构与release build的std :: wstring不同(例如,如果你尝试打印std :: wstring实例的原始sizeof,你可以在发布版本和调试版本中找到不同的数字) .因此,使用/ MD构建的EXE期待release-build的std :: wstring;相反,使用/ MDd构建的DLL期望调试构建的std :: wstring:这两个期望之间存在不匹配(一个模块期望X类,但另一个模块正在给Y类),因此您遇到了崩溃.

猜你在找的C&C++相关文章