结果通过值传递,在C期间被破坏 - > C ++回调函数(gcc 4.1)

时间:2012-08-24 16:48:03

标签: c++ c linux gcc callback

情景就是这样。我看到一个struct在被值传递给回调函数时会被破坏,从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函数并将其调用只是为了测试,那么结构就会很好地复制而不会损坏。

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

如果我更改回调函数以通过指针而不是复制传递结构,它可以正常工作!唉,C API有ABI限制,无法修改。

它闻起来像某种调用约定或结构布局问题,但我不知道为什么这样的旋钮转动。总的来说,struct是16个字节,因此它不会向我发出堆栈问题。

1 个答案:

答案 0 :(得分:1)

这似乎与优化级别有关。代码正在使用-O0构建并且失败,现在使用-O1它可以工作。没有兴趣深入挖掘!