我正在对现有的linux c项目进行一些更改。
在/vobs/ua/HDL/VHDL/CmdUtil/src/help.c
中,我将func定义为:
void func(){
...
}
在文件/vobs/ua/HDL/Interface/cli/src/cliSystem.C
中,我写了这段代码:
extern void func();
...
void func1(){
...
func();
...
}
在文件/vobs/ua/HDL/VHDL/DsnMgr/src/shell.c
中,我写了这个:
extern void func();
...
void func2(){
...
func();
...
}
在文件/vobs/ua/HDL/VHDL/DsnMgr/src/shell.c
中,我写了这个:
extern void func();
...
void func2(){
...
func();
...
}
在文件/vobs/ua/HDL/VHDL/lib2v/src/asicLibCells.C
中,我写了这个:
extern void func();
...
void func3(){
...
func();
...
}
我没有在任何头文件中声明func。
问题是,对于在vobs / ua / HDL / Interface / cli / src / cliSystem.C和/vobs/ua/HDL/VHDL/lib2v/src/asicLibCells.C中调用func,有错误< / p>
对`func()'
的未定义引用
但对于/vobs/ua/HDL/VHDL/DsnMgr/src/shell.c
,没有错误。
我在func
和vobs/ua/HDL/Interface/cli/src/cliSystem.C
中声明/vobs/ua/HDL/VHDL/lib2v/src/asicLibCells.C
之后:
extern "C" void func();
/vobs/ua/HDL/VHDL/lib2v/src/asicLibCells.C
中没有错误,但vobs/ua/HDL/Interface/cli/src/cliSystem.C
中的错误仍然存在。
怎么了?如何消除此错误?
答案 0 :(得分:2)
问题是函数func
是一个C函数,你试图从C ++函数调用它。这是有问题的,因为C ++做了一些名为name mangling的事情来允许函数重载等事情。
这意味着当你做宣言时
extern void func();
C ++编译器将 mangle 符号,并且找不到损坏的符号。
在C ++中,您必须禁止对来自C对象文件的函数进行此名称修改。这是通过特殊的extern
声明完成的:
extern "C" void func();
在一个稍微相关的说明中,在C中声明如
void func();
并不意味着该函数不像C ++中那样使用任何参数。在C中,声明意味着func
采用未指定数量的未指定参数。在C中你必须使用void
来声明一个不带参数的函数:
void func(void);
答案 1 :(得分:1)
C ++有一个名为mangling的东西,所以你可以重载函数。如果您正在将代码编译为C ++,那么声明
extern void func(void);
会在其名称中添加额外的字符,以编码它没有参数的事实。您可以通过告诉C ++编译器使用C约定来禁用它:
extern "C" void func(void);
或
extern "C" {
void func(void);
}
然而,将它们放在可以包含在C和C ++文件中的标题中是正常的:
#if defined __cplusplus
extern "C" {
#endif
void func(void);
// other function declarations
#if defined __cplusplus
}
#endif