由值传递的结构,在 C -> C++ 回调函数期间损坏 (gcc 4.1)

Struct passed by value, corrupted during C -> C++ callback function (gcc 4.1)

本文关键字:函数 回调 损坏 gcc C++ 结构 值传 gt      更新时间:2023-10-16

场景是这样的。我看到一个结构在通过值传递到回调函数时被破坏,从一个C API传递到一个C++函数(通过一个静态方法)。

库A:基于C的API,通过gcc构建库B:基于C++的API,通过g++构建

库A是作为一个静态库构建的,带有-fPIC。库B被构建为一个共享库,链接库a,也使用-fPIC构建。

在库A中定义的是一个结构:

typedef struct doomed_struct
{
    uint32_t field1;
    uint32_t field2;
    CHILD_STRUCT1 field3;
    CHILD_STRUCT2 field3;
} DOOMED_STRUCT;

和一个回调函数:

typedef void (_CALLBACK_FUNC *FUNCTION)(uint32_t arg1, uint8_t arg2,
    uint8_t arg3, DOOMED_STRUCT arg4);

C++API在类中定义了一个静态方法,并将其交给C API进行回调。当调用此回调时,简单类型的arg1,2,3会使其恢复正常,但结构中的字段是垃圾,每次执行时都会发生变化。

我也尝试过将C++API的函数更改为extern "C"静态函数,但没有成功。

如果我在C API中截取一个C函数并调用它只是为了测试,那么结构复制得很好,不会损坏。

令人沮丧的部分?这一切在MSVC8/9/10、Linux和QNX上的gcc 4.4.x(32和64位)上都能很好地工作。回到几年前的gcc 4.1,这会弹出。

如果我将回调函数改为通过指针而不是复制来传递结构,它会很好!遗憾的是,C API有ABI限制,不能修改。

这闻起来像是某种调用约定或结构布局问题,但我不知道该为这样的事情打开什么旋钮。总的来说,这个结构是16个字节,所以它对我来说不会引起堆栈问题。

这似乎与优化级别有关。代码是用-O0构建的,但失败了,现在用-O1它就可以工作了。没有兴趣再深入挖掘了!