我在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?
答案 0 :(得分:10)
您应该使用相同的调试CRT (/MDd
编译器选项)检查EXE和DLL是否动态链接。确保EXE和DLL的其他设置(如_HAS_ITERATOR_DEBUGGING
)也相同。
(一种捷径可能只是在类接口上使用const wchar_t*
而不是std::wstring
,只需从构造函数体内的原始指针构建std::wstring
。
编辑:您确认CRT不匹配(即使用/MD
构建的EXE与使用/MDd
构建的DLL)是问题所在。事实是,相同的类名std::wstring
表示调试版本(/MDd
)和发布版本(/MD
)中的两个不同的类。实际上,在调试版本中,类实现中可以有其他机制来帮助调试;这种机制可能会导致效率低下,因此在发布版本中将其删除。因此,调试版本std::wstring
的内部结构与发布版本std::wstring
不同(例如,如果您尝试打印sizeof
个std::wstring
实例,可以找到不同的数字在发布版本和调试版本中)。因此,使用/MD
构建的EXE期待发布版本std::wstring
;相反,使用/MDd
构建的DLL期望调试构建的std::wstring
:这两个期望之间存在不匹配(一个模块期望类X
但另一个模块正在提供类{{1}因此你崩溃了。