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

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)

Soo*_*nts 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