我想要一种内联方式来指定哪些原型应该包含在c中 . 例如:
void ArrayList_insert(ArrayList *arrlst, void *data, int i);
IS_CPP void ArrayList_insert(ArrayList *arrlst, char *data, int i);
IS_CPP void ArrayList_insert(ArrayList *arrlst, Buffer *data, int i);
目前我在做:
#ifdef __cplusplus
extern "C" {
#endif
....C HEADERS..
#ifdef __cplusplus
}
....C++ HEADERS...
#endif
但它非常不方便,因为相同功能的重载在不同的地方 . 我可以只有两个不同的头文件,但这也很痛苦 . 因此,我正在寻找像我上面提出的内联解决方案 . 有谁知道这样做的方法?
5 回答
它比你想象的容易 .
使用这种类型的 Headers :
当然,通过使用类似函数的宏,你几乎可以像你的例子那样做:
现在,如果您将标头编译为C,那么'll get all three, but if you compile as C, you' ll只会得到一个 . 如果要在两者之间共享一个库,则在编译C时需要向C函数添加一些
extern "C"
限定符 . @MarkLakata的回答显示了一种可能的方式 .通常的方法是以最明显的方式编写它:
正如@ chacham15指出的那样,你还需要在项目范围的 Headers 中,
你需要用
EXTERN_C
来装饰C-callable函数 .你显然可以滥用预处理器来破解你所要求的内容,但为什么呢?就个人而言,如果我使用C,我宁愿输入
mylst.insert(foop, 1);
而不是ArrayList_insert(mylst, foop, 1);
. 换句话说,我认为使用C样式调用重载函数没什么好处,但是混合代码作者创建的函数调用样式也不是很完美 .我将创建一个与C结构中的成员相同的ArrayList类,并且只要需要将类与C函数接口,就可以创建一个浅表副本并将其传递给C函数,然后从中复制信息 . 那个结构回到你的 class .
另一种方法是将结构包装在C类中,并将其用于C接口函数 .
否则,您可能会尝试使类继承C结构,假设结构的标记未命名为ArrayList,并且从C接口看不到结构的typedef . 然后你可以直接从成员函数中传递this指针,就好像它是实际的C结构一样 . 我不确定这种方法在所有情况下都是可移植的,所以如果可能的话我会实现前一个想法,即使它确实需要来回复制数据 .
所有的想法都避免了代码重复,C接口看起来更像C代码,而不是C函数和C函数重载的错误混合 . 另外,接口在某种程度上是分开的 . 不需要额外的头文件,因为C函数可以像往常一样包装在extern“C”块中:
如果你真的想摆脱样板并且你愿意使用预处理器去做,那么就继续写下模式 . 你看起来的一般模式
所以你可以做一个宏,
这是有效的,因为普通的函数声明不能包含括号括起来的逗号 . 如果您希望它使用模板(使用逗号分隔的模板参数),那么您可以使用C99,C 11中支持的可变参数宏以及这些标准之前的各种编译器作为扩展 .
现在只要C声明不包含裸逗号,这就行了,这意味着你不应该_1158982_称它为
C_PORTABLE_FUNCTION_SET
强调它主要是安全的用于函数声明,但请注意你需要在extern C
中声明C可访问的对象为好 . 共享的struct
定义根本不受保护;它们受C POD概念保护,不带语言链接 .用法:
我不认为我自己会这样做,但似乎足够安全,成为惯用语 .