从dll内部调整向量大小时,为什么会出现堆损坏?

时间:2019-06-20 11:08:48

标签: c++ dll heap-corruption xll

我正在编写一个调用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;
}

1 个答案:

答案 0 :(得分:5)

要跨DLL边界传递对std :: vector或其他C ++集合的引用,您需要执行以下操作。

  1. 对两个模块使用相同的C ++编译器,并使用相同版本的编译器。

  2. 在项目设置中,设置与“常规/平台工具集”相同的值。

  3. 在项目设置中,将C / C ++ /代码生成/运行时库值设置为“多线程DLL(/ MD)”,或将多线程调试DLL(/ MDd)设置为调试配置。如果其中一个项目具有需要静态CRT设置的依赖项,那么很遗憾,您将不起作用。

  4. 在两侧使用相同的配置:如果您已构建DLL的调试版本,请不要与使用该EXE的发行版链接。另外,请勿更改_ITERATOR_DEBUG_LEVEL或_SCL_SECURE_NO_WARNINGS之类的预处理器定义,否则,请对两个项目将其更改为相同的值。

这些并发症的原因是C ++没有标准化的ABI。 std :: vector和其他类的内存布局基于许多因素而变化。运算符newdelete也在C ++标准库中,也就是说,您不能在一个模块中分配使用C ++的内存,而不能在另一个模块中分配内存。

如果您不能满足这些条件,则有几种解决方法,下面是一个不错的摘要:https://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL