我正在编写一个调用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;
}
答案 0 :(得分:5)
要跨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