c++ - 制作dll - vs工程调用dll



无法通过DLL传递std:: wstring (1)

我已经在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复制?


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

(一个快捷方式可以在类接口中使用const wchar_t*而不是std::wstring ,并且只需从构造函数体内的原始指针构建一个std::wstring )。

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





dll