无法通过的std ::跨DLL的wstring(Unable to pass std::wstrin

2019-07-20 20:48发布

我已经设置了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导出的类。 但是,测试框架报告意外的异常。 我跟踪它到std::wstring “复制字符串时的拷贝构造函数Foobar的构造。 的MSVC调试器报告源字符串作为<Bad Ptr>

我创建了一个虚拟的构造函数, Foobar::Foobar(long num, IDbService& db)和所有的值(包括IDbService&遇到就好了。

无论是MFC DLL和我的单元测试EXE共享应保持编译器标志相当于一个属性表。 我在构建和运行在调试模式下进行测试。 任何想法,为什么std::wstring不能跨越DLL复制?

Answer 1:

您应该检查,无论是EXE和DLL 动态使用相同的调试CRT( /MDd的编译器选项)。 确保像还有其他设置_HAS_ITERATOR_DEBUGGING都为EXE和DLL都相同。

(快捷方式可以只使用const wchar_t*代替std::wstring在类的界面,只是建立std::wstring从原始指针构造函数体内)。

编辑 :你证实,CRT错配(即EXE建有/MD与内置DLL /MDd )是问题。 事实是,相同的类名std::wstring手段在调试两个不同的类构建( /MDd ),并在发布版本( /MD )。 事实上,在调试版本就不可能有一流的实施,帮助调试内的其他机制; 这种机制可以引入低效率,所以在发布版本它删除。 因此,调试版本的内部结构std::wstring是发布版本的不同std::wstring (例如,如果你尝试打印原始sizeofstd::wstring情况下,你可以找到不同的号码在发布版本和调试版本) 。 因此,内置的EXE /MD期待发布版本的std::wstring ; 而不是内置的DLL /MDd期待调试建造的std::wstring :有(一个模块期待类这两种预期之间的不匹配X ,但其他模块所赐类Y ),并让你有一个崩溃。



文章来源: Unable to pass std::wstring across DLL