我在C ++项目中使用外部C库。
标头包含一个带有名为class
的变量的结构:
#ifdef __cplusplus
extern "C" {
#endif
struct something_t {
...
sometype class;
};
#ifdef __cplusplus
}
#endif
g ++不喜欢这个并且抱怨“错误:'之前的预期标识符';'令牌”。
我有哪些选择?
class
,但这很麻烦并打破了上游兼容性。class
:#define class class_
是否有任何副作用?处理这种情况的最佳方法是什么?
结果: 根据选项2的主流偏好,我最终选择在上游库中重新命名。
答案 0 :(得分:13)
正如其他人在评论中已经提到的那样,最好的选择就是围绕这些东西编写另一个C API层,它只在内部使用其他API。
与此违规struct
定义相关的任何内容都应仅通过不透明指针导出。
在C ++中,您可以使用已清理的C-API。
这是一张小草图:
ThirdParty.h
(包含使用c ++编译的违规代码)
#ifdef __cplusplus
extern "C" {
#endif
struct something_t {
...
sometype class;
};
struct something_t* CreateSomething(); // Does memory allocation and initialization
void DoSomething(struct something_t* something);
#ifdef __cplusplus
}
#endif
<强> MyApiWrapper.h
强>
#ifdef __cplusplus
extern "C" {
#endif
typedef void* psomething_t;
struct psomething_t MyCreateSomething(); // Does memory allocation and initialization
void MyDoSomething(psomething_t something);
#ifdef __cplusplus
}
#endif
<强> MyApiWrapper.c
强>
#include "ThirdParty.h"
struct psomething_t MyCreateSomething() {
psomething_t psomething = (psomething_t)CreateSomething();
return psomething;
}
void MyDoSomething(psomething_t something) {
DoSomething((struct something_t*)psomething);
}
关于您考虑的解决方案
- 我可以要求上游项目重命名变量,但这可能很难
醇>
你当然应该报告这个错误让他们知道。如果它是一个git-hub托管项目,则准备一个pull请求。
无论如何都要准备好他们可能没有及时回应,你应该总是有上面提到的&#34;计划B&#34; 。它无论如何都会有用......
- 我可以使用预处理器重新定义标题中的类:#define class class_有副作用吗?
醇>
这可能是一种可行的方式,如果出现此特定符号(class
)的任何地方是普通c代码而第三方c代码的其他部分(例如作为库)则不依赖于该符号(其中不太可能)。