无法跨DLL传递std::wstring
Unable to pass std::wstring across DLL
我在Visual Studio 2010中建立了一个项目,针对现有的MFC DLL编写单元测试。我使用的是单头单元测试框架,并从单元测试项目链接到MFC DLL的库包装器。我试图构建一个类,在它的构造函数中需要一个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
编译器选项)动态链接。确保其他设置,如_HAS_ITERATOR_DEBUGGING
,对于EXE和DLL都是相同的。
(一种快捷方式可以是在类接口上使用const wchar_t*
而不是std::wstring
,并从构造函数体内的原始指针构建std::wstring
)。
EDIT:您确认CRT不匹配(即使用/MD
构建的EXE与使用/MDd
构建的DLL)是问题所在。事实上,相同的类名std::wstring
在调试版本(/MDd
)和发布版本(/MD
)中意味着两个不同的类。事实上,在调试构建中,类实现中可以有额外的机制来帮助调试;这种机制会导致效率低下,所以在发布版本中被移除。因此,调试版本的std::wstring
的内部结构不同于发布版本的std::wstring
(例如,如果你试图打印std::wstring
实例的原始sizeof
,你可以在发布版本和调试版本中找到不同的数字)。因此,使用/MD
构建的EXE期待发布std::wstring
;相反,用/MDd
构建的DLL期望调试构建的std::wstring
:这两个期望之间存在不匹配(一个模块期望类X
,但另一个模块给出类Y
),所以你有一个崩溃。
- -fshort-wchar 和 std::wstring - 分段错误
- 如何将std::wstring转换为char const[]
- 将utf16宽std::wstring转换为utf8窄std::string以获得罕见字符时出现问题
- 找不到 std::wstring 中存在的wchar_t
- 将整数附加到 std::wstring 会给出错误
- 使用STD :: WSTRING或WCHAR_T登录
- 从 std::wstring 转换为 jstring
- UTF8 数据到 std::string 或 std::wstring
- 将 std::u16string 转换为 std::wstring,无需复制
- 从相同的硬编码字符串文字初始化std::string和std::wstring
- std::wstring中ASCII符号的字节表示,具有不同的语言环境
- std::wstring 和 LOGFONT 重载冲突 - 为什么?
- 为什么我的 BSTR 到 std::wstring 的转换这么慢?我的测试仪不好吗?
- 将 std::string 移植到 std::wstring,反之亦然
- 从DLL返回std::wstring是否安全
- 在std::string和std::wstring之间转换的多平台方式
- 正在将std::wstring转换为const wchar_t x[]
- std::wstring指针赋值C++
- porting std::wstring to gcc cygwin
- 结合 std::wstring 和函数