Con*_*ngo 33 c++ visual-studio-2012
我正在调用一个静态链接的.dll,我看到这个错误:

我写了.dll和调用代码.不应该发生此错误.我想知道是否有其他人以前遇到过它?.dll只包含大约10行代码,它只是一个测试.dll来查看dll如何工作.当我从.dll传回一个std :: string时它会爆炸.
我正在使用Visual Studio 2012和C++.
接下来我会尝试什么
来自Debug断言... _pFirstBlock == pHead:
如果在多线程模块中使用单线程库,则会发生此问题.
明天,我将尝试在多线程模式下重新编译Boost静态库(我的.dll设置为多线程静态模式).
接下来我会尝试什么
你需要做两件事之一
- 使DLL和使用它的客户端都链接到 CRT 的DLL版本(例如,不静态).
- 或者您需要确保不跨DLL边界传递动态分配的内存(例如字符串对象中包含的内存).换句话说,没有返回字符串对象的DLL导出函数.
乔
这似乎与正在发生的事情相匹配,它在我将字符串传回.dll边界的精确点处爆炸.只有在静态模式下链接所有内容时才会出现此问题.现在这是可以解决的.
接下来我会尝试什么
解
我有一个很好的解决方案,请参阅下面的答案.
Con*_*ngo 38
在这种情况下,问题是我正在std::string向后传递.dll边界.
如果MSVC Runtime library设置为Multi-threaded Debug DLL (/MDd),那么这没有问题(它工作正常).
如果MSVC Runtime library设置为Multi-threaded Debug (/MTd),则会抛出此错误,可以使用以下说明修复此错误.
问题是内存是在.dll端分配的,然后在应用程序端释放相同的内存.这意味着内存管理器A正在分配内存,而内存管理器B正在释放生成错误的相同内存.
解决方案是确保传回的所有内存都不在DLL中分配.换句话说,内存总是在应用程序端分配,并在应用程序端释放.
当然,DLL可以在内部分配/释放内存 - 但是它不能分配稍后由应用程序释放的内存.
这将不工作:
// Memory is allocated on the .dll side, and freed on the app side, which throws error.
DLL std::string GetString();
Run Code Online (Sandbox Code Playgroud)
这将有效:
// Memory is allocated/freed on the application side, and never allocated in the .dll.
DLL int GetString(std::string& text);
Run Code Online (Sandbox Code Playgroud)
但是,这还不够.
在应用程序端,必须预先分配字符串:
std::string text("");
text.reserve(1024); // Reserves 1024 bytes in the string "text".
Run Code Online (Sandbox Code Playgroud)
在.dll端,必须将文本复制到原始缓冲区中(而不是使用.dll端分配的内存覆盖):
text.assign("hello");
Run Code Online (Sandbox Code Playgroud)
有时,C++仍会坚持分配内存.仔细检查预分配是否仍然如下:
if (text.capacity < 1024)
{
cout << "Memory was allocated on the .dll side. This will eventually throw an error.";
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用std::shared_ptr<std::string>,所以即使在.dll中分配了内存,它也会被.dll(而不是应用程序端)释放.
另一种方法是接受char *指示预分配存储量的a 和长度.如果我们要传回的文本长于预分配内存的长度,则返回错误.
| 归档时间: |
|
| 查看次数: |
21483 次 |
| 最近记录: |