【问题标题】:Heap/Stack corruption on DLL callDLL 调用上的堆/堆栈损坏
【发布时间】:2011-07-26 11:35:36
【问题描述】:

我正在尝试在代码块(在 mingw 下使用 GCC)中使用 Visual Studio 2008 SP1 创建的 dll(启用公共语言运行时支持)。传递给 dll 的一些参数已由调用函数动态分配。我的问题是:

“传递给 dll 的参数能否驻留在调用函数的堆上。这样做安全吗?”

从 dll 返回时,调用函数的堆栈已损坏,并且在尝试访问这些堆栈时,当我尝试调试此问题时,我在代码块中得到一个 SIGTRAP。

这可能是什么原因?

dll函数的原型是这样的:

int __cdecl myTesseractOCR(myOCRData* labels_for_ocr);

myOCRDaata 定义如下:

typedef struct __ocr_data
{
    char* arr_image       [NUMOBJ_LIMIT_HIGH];
    int   start_x         [NUMOBJ_LIMIT_HIGH];
    int   start_y         [NUMOBJ_LIMIT_HIGH];
    int       width               [NUMOBJ_LIMIT_HIGH];
    int       height              [NUMOBJ_LIMIT_HIGH];
    int       widthstep           [NUMOBJ_LIMIT_HIGH]; 
    char      number_plate_buff   [2*NUMOBJ_LIMIT_HIGH];
    int       ocr_label_count;
} myOCRData;

arr_image 指向驻留在调用函数堆上的数据,而上述结构的所有其他成员都驻留在调用函数的堆栈上。驻留在堆栈上的所有这些成员都会损坏,程序会生成一个 SIGTRAP。我已经看到在 stackoverflow 的各个线程中都在讨论这些问题,但还没有找到具体的解决方案。

【问题讨论】:

    标签: c visual-studio-2008 gcc


    【解决方案1】:

    我建议您使您的 DLL 接口尽可能扁平;即避免通过结构,即使它们是 POD。由于您使用的是 2 个不同的编译器,因此这一点尤为重要。如果您决定传递结构,请确保在两个编译器下都明确定义了结构的打包。

    【讨论】:

    • 我不同意。将结构传递给从 DLL 导出的函数是完全常规的做法。 Win32 广泛依赖这一点,它工作得非常好。
    • @David Heffernan 只要结构包装相同,它就可以工作。由于 OP 使用 2 个编译器,不同的打包可能是他看到的损坏的原因。
    • 这确实是一个可能的原因,修复起来很简单。
    • 嘿Praetorian...谢谢,听起来是一个正当的理由,我会把它们弄平,看看它是否有效...我完全错过了结构包装......
    【解决方案2】:

    DLL 访问驻留在调用应用程序堆上的内存是完全合理的。如果你不能这样做,那么 DLL 基本上就没有用了。

    您的问题一定出在其他地方。很可能您没有正确设置调用 DLL 的参数。

    【讨论】:

      【解决方案3】:

      您能否交叉检查 GCC 和 DLL 约定 VS2kSP1 CLR 的调用约定标志

      【讨论】:

        【解决方案4】:

        堆不属于函数。在一个模块中分配内存并将其传递给另一个模块是非常好的,只需确保分配内存的模块是释放它的模块。
        麻烦的第二个来源可能是不同的调用转换。为所有导出的函数指定调用约定。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-03-11
          • 2013-05-02
          • 2017-06-07
          • 2015-07-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多