题
我写了一个C ++函数,我需要从C程序调用。以使其由C来调用,我指定的功能的声明强> extern "C"
。然后我编译的C ++代码,但是编译器(Dignus系统/ C ++)产生的重整名称以功能。因此,它显然没有兑现extern "C"
。
要解决此问题,我添加extern "C"
给函数的定义即可。在此之后,所产生的编译的函数名称是由C来调用。
技术上,extern "C"
只需要在函数声明中指定。这是正确的吗? (该 C ++ FAQ精简版有一个很好的例子。)如果你还可以指定它的函数定义?
下面是证明这样的示例:
/* ---------- */
/* "foo.h" */
/* ---------- */
#ifdef __cplusplus
extern "C" {
#endif
/* Function declaration */
void foo(int);
#ifdef __cplusplus
}
#endif
/* ---------- */
/* "foo.cpp" */
/* ---------- */
#include "foo.h"
/* Function definition */
extern "C" // <---- Is this needed?
void foo(int i) {
// do something...
}
我的问题可能是不正确编码的东西的结果,或者我可能已经找到了编译器错误。在任何情况下,我想请教计算器,以确保我知道这在技术上是“正确”的方式。的
解决方案
在“extern "C"
”不应该被在功能上确定指标只要声明有它和已经出现在定义的运用汇编必需的。标准明确规定(7.5 / 5联动规格):
一个函数可以没有明确的链接说明被看见后连杆规范声明;在原先的声明明确指定联动不受这样的函数声明。
然而,我一般把“extern "C"
”上把定义为好,因为它实际上是在与外部的“C”键的功能。很多人讨厌不必要的,多余的东西是声明(就像把virtual
的方法覆盖),但我不是其中之一。
其他提示
修改的结果, 好像我误解了问题。 反正,我尝试:
// foo.cpp
/* Function definition */
#include "foo.h"
void foo(int i) {
//do stuff
}
void test(int i)
{
// do stuff
}
// foo.h
#ifdef __cplusplus
extern "C" {
#endif
/* Function declaration */
void foo(int);
#ifdef __cplusplus
}
#endif
void test(int);
使用命令nm
从编译的文件查看符号:
linuxuser$ nm foo.o
00000006 T _Z4testi
U __gxx_personality_v0
00000000 T foo
这清楚地表明的函数名称为extern“C”声明不错位,并在定义不需要外部的“C”关键字。搜索 收到了所需的每一个C库代码写入没有外部的“C”,在C ++程序本来无法使用。
就遇到过这种情况......不愉快的经历。
下面被宣布在我c
文件之一:
void unused_isr(void) {}
void ADC_IRQHandler(void) __attribute__ ((weak, alias("unused_isr")));
接下来某处我所定义的cpp
文件:
void ADC_IRQHandler(void) {
...
}
和忘了向前声明更改为:
void ADC_IRQHandler(void);
我花了一段时间之前,我想通了,我做的一切权利相对于AD转换,但我没有“外部C”添加至定义!
extern "C" void ADC_IRQHandler(void) {
...
}
只是我的两分钱为什么它可能是在某些情况下非常有用的习惯将它添加到定义为好。
我觉得这需要在这里澄清,我刚才也有类似的问题,我花了一段时间才能得到这个明确的在我的脑海中,只有布鲁克斯摩西谈到了这个正确的,我觉得它需要说更多显然...
在总结该头可以把你扔出,所有的编译器看到的是cpp文件,如果头没有被包含在外部的“C”回你的CPP(我通常看到的),那么为extern“C”将需要在cpp文件的地方(无论是在清晰度,或另一份声明),使CXX编译器能够知道C链接,使之,编译器不关心的报头,只有连接。
不需要围绕定义中的extern "C"
。你可以逃脱只是把它周围的声明。在你的例子一个音符...
#ifdef __cplusplus
extern "C" {
#endif
/* Function declaration */
void foo(int);
#ifdef __cplusplus
}
#endif
您的代码正在寻找的预处理宏“__cplusplus
”。
虽然它的普遍实现,这取决于你的编译器,这可能会或可能不会进行定义。在你的榜样,您还可以使用 extern "C"
周围的声明,但有你的不是检查了“__cplusplus
”宏观调控这就是为什么我怀疑它的工作,一旦你这样做。
见下面的评论 - 标准C ++要求__cplusplus
宏由预处理器来定义
它应该在两者。编译器需要知道使用C符号名和编译调用点(可能只看到一个声明)时调用约定,编译器也需要知道生成C符号名称和使用C编译时调用约定函数定义本身(这可能看不到任何其他声明)。
现在,如果你有一个extern-C声明是在其中定义存在翻译单元可见,你可以逃脱自定义离开关的extern-C,但我不知道这是肯定。