c++ - 在 C++ 中处理 C 库匿名结构类型

标签 c++ c gcc name-mangling anonymous-struct

我们有一个大型、旧的 C++ 应用程序,其中包含大量遗留代码和一些用 C 编写的外部库。这些库很少更新——只有在我们发现错误并且供应商提供补丁时才会更新。上周在一个库中发生了这种情况,在集成新版本后,我们发现如果我们不在本地修改库(我们显然对上一个版本做了修改),我们的构建就会中断并显示以下错误消息:

non-local function ‘static E* MyCls::myFct(<anonymous struct>*)’ uses anonymous type

这是由于库声明了许多这样的句柄类型:

#define _Opaque struct {unsigned long x;} *

typedef _Opaque    Handle;
typedef _Opaque    Request;

我们在某些类的函数签名中使用:

class MyCls {
public:
    static void* myFct(Handle handle);
    ...
}

这会产生上述错误,因为编译器无法为函数创建一个正确的名称混淆名称,因为 _Opaque 结构没有名称。

我们目前的解决方法是修补库头文件,明确地为结构命名:

//#define _Opaque struct {unsigned long x;} * //Replaced by typedef below!
typedef struct __Opaque {unsigned long x;} * _Opaque;

这显然很糟糕,因为如果可能的话我们不想碰图书馆。另一个更糟糕的选择是将所有函数签名中的类型转换为 void* 并将它们转换回各自的类型。在纯 C 中重写每个受影响的函数是最糟糕的选择...

所以,我的问题是:有没有比修补库更好的选择?我忽略了一个简单的解决方案吗?解决此问题的最佳方法是什么?

最佳答案

您可以通过对 #define 行进行最小的更改来完成此操作,利用 7.1.3:8 中的规则,声明声明的第一个 typedef-name 是 该类类型(或枚举类型)仅用于表示用于链接目的的类类型(或枚举类型):

#define MAKE_DUMMY2(line) dummy_ ## line
#define MAKE_DUMMY(line) MAKE_DUMMY2(line)
#define _Opaque struct {unsigned long x;} MAKE_DUMMY(__LINE__), *

这为 HandleRequest 等提供了最小的链接。

关于c++ - 在 C++ 中处理 C 库匿名结构类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11933713/

相关文章:

c++ - 无法让 std::ignore 在范围内的结构化绑定(bind)中工作

c++ - 使用 {0} 初始化结构

android - 尝试在 Cocos2d-X C++ 中设置一个带有整数的 CCLabelTTF 作为其字符串的一部分

c++ - 对角展平矩阵的邻域索引计算

c - (gvim 8271) IBUS 警告

c++ - 无法使用 static_cast 将枚举类转换为 int

linux - 我在使用mpicc进行编译时遇到技术问题

c++ - 获取 Eigen C++ 库 Vector 的最大系数的位置

c++ - 将 C++11 代码转换为 C++98

c - 如何在同一个 .c 文件中编写汇编和 C 代码