Eri*_*rik 1 c++ dll xll heap-corruption
我正在编写一个调用DLL函数的XLL(使用XLW库)。该DLL函数将获取向量引用,修改向量并通过参数返回。
我有一个VS10解决方案,其中包含几个c ++项目,一些DLL和XLL,它们将从excel调用DLL函数。我使用VS10编译器编译了所有内容_HAS_ITERATOR_DEBUGGING=0,_CRT_SECURE_NO_WARNINGS并使用和为所有项目使用了相同的运行时库(/ MDd)。
我还必须重建XLW库以符合_HAS_ITERATOR_DEBUGGING=0我在项目中必须使用的库。
调用xll_function时,出现堆损坏错误,无法弄清原因。在调用dll函数之前尝试调整向量的大小后,错误发生了。也就是说,我可以调用该函数并获取由参数返回的正确向量,并且不会造成堆损坏。
有人可以阐明这一点吗?由于我不熟悉DLL,因此不知道这是否应该发生或我做错了什么。
正如您在下面的代码中看到的那样,dll函数将尝试调整大小forwards,这就是我认为正在生成堆错误的地方。我试图了解为什么会发生这种情况,以及这种调整大小和分配方式对dll的影响。也许我无法调整在另一个堆中分配的向量的大小。
**下面的代码-第一个函数是dll项目中类的静态方法,第二个函数导出到XLL。
void dll_function(double quote, const std::vector<double>& drift, const std::vector<double>& divs, std::vector<double>& forwards)
{
size_t size = drift.size();
forwards.resize(size);
for( size_t t = 0; t < size; t++)
{
forwards[t] = (quote - divs[t]) * drift[t];
}
}
MyArray xll_function(double quote, const MyArray& drift, const MyArray& divs)
{
// Resizing the vector before passing to function
std::vector<double> forwards(drift.size());
dll_function(quote, drift, divs, forwards);
return forwards;
}
Run Code Online (Sandbox Code Playgroud)
要跨DLL边界传递对std :: vector或其他C ++集合的引用,您需要执行以下操作。
对两个模块使用相同的C ++编译器,并使用相同版本的编译器。
在项目设置中,为“常规/平台工具集”设置相同的值。
在项目设置中,将C / C ++ /代码生成/运行时库值设置为“多线程DLL(/ MD)”,或将多线程调试DLL(/ MDd)设置为调试配置。如果其中一个项目具有需要静态CRT设置的依赖项,对不起,您不走运,它将无法正常工作。
双方都使用相同的配置:如果您已构建DLL的调试版本,请不要与使用该EXE的发行版链接。同样不要更改预处理器的定义,例如_ITERATOR_DEBUG_LEVEL或_SCL_SECURE_NO_WARNINGS,或者,如果更改,则将两个项目的它们都更改为相同的值。
这些并发症的原因是,C ++没有标准化的ABI。std :: vector和其他类的内存布局基于许多因素而变化。运算符new和delete也在C ++标准库中,即,您不能在一个模块中使用C ++分配内存,而不能在另一个模块中分配内存。
如果您不能满足这些条件,则有几种解决方法,下面是一个不错的摘要:https : //www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL
| 归档时间: |
|
| 查看次数: |
127 次 |
| 最近记录: |