我正在调用一个静态链接的.dll,我看到这个错误:

我写了.dll和调用代码.不应该发生此错误.我想知道是否有其他人以前遇到过它?.dll只包含大约10行代码,它只是一个测试.dll来查看dll如何工作.当我从.dll传回一个std :: string时它会爆炸.
我正在使用Visual Studio 2012和C++.
接下来我会尝试什么
来自Debug断言... _pFirstBlock == pHead:
如果在多线程模块中使用单线程库,则会发生此问题.
明天,我将尝试在多线程模式下重新编译Boost静态库(我的.dll设置为多线程静态模式).
接下来我会尝试什么
你需要做两件事之一
- 使DLL和使用它的客户端都链接到 CRT 的DLL版本(例如,不静态).
- 或者您需要确保不跨DLL边界传递动态分配的内存(例如字符串对象中包含的内存).换句话说,没有返回字符串对象的DLL导出函数.
乔
这似乎与正在发生的事情相匹配,它在我将字符串传回.dll边界的精确点处爆炸.只有在静态模式下链接所有内容时才会出现此问题.现在这是可以解决的.
接下来我会尝试什么
解
我有一个很好的解决方案,请参阅下面的答案.
我无法弄清楚以下崩溃的原因(MSVC9):
//// the following compiles to A.dll with release runtime linked dynamically
//A.h
class A {
__declspec(dllexport) std::string getString();
};
//A.cpp
#include "A.h"
std::string A::getString() {
return "I am a string.";
}
//// the following compiles to main.exe with debug runtime linked dynamically
#include "A.h"
int main() {
A a;
std::string s = a.getString();
return 0;
} // crash on exit
Run Code Online (Sandbox Code Playgroud)
显然(?)这是由于可执行文件和DLL的不同内存模型.可能是字符串A::getString()返回是在A.dll中分配并在main.exe中释放?
如果是这样,为什么 - 以及在DLL(或可执行文件)之间传递字符串的安全方法是什么?不使用shared_ptr这样的包装器和自定义删除器.
根据一些较旧的StackOverflow问题(无法通过DLL传递std :: wstring,C++ DLL返回指向std :: list <std :: wstring>的指针),对于C++ DLL返回a并不安全,std::wstring因为不能保证main程序具有相同的定义,std::wstring因此可能导致崩溃.
但是,在http://en.cppreference.com/w/cpp/string/basic_string中,它现在似乎std::wstring可以与WCHAR数组互换使用:
(从C++ 11开始)basic_string的元素是连续存储的,也就是说,对于basic_string s,&*(s.begin()+ n)==&*s.begin()+ n对于任何n in [0,s.size()),或者,等效地,指向s [0]的指针可以传递给期望指向CharT []数组的第一个元素的指针的函数.
我已经通过传递&s[0]给期望WCHAR*缓冲区的WINAPI函数测试了它,它似乎工作(std::wstring正确填充了WINAPI的结果).所以既然std::wstring现在显然可以像对待WCHAR数组一样对待,我决定重新审视这个问题:可以std::wstring从DLL中安全地返回吗?为什么或者为什么不?