对“func()”的未定义引用
undefined reference to `func()'
我正在对现有的 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,有错误
undefined reference to `func()'
但是对于/vobs/ua/HDL/VHDL/DsnMgr/src/shell.c
,没有错误。
我在 vobs/ua/HDL/Interface/cli/src/cliSystem.C
和 /vobs/ua/HDL/VHDL/lib2v/src/asicLibCells.C
中声明 func
之后,像这样:
extern "C" void func();
/vobs/ua/HDL/VHDL/lib2v/src/asicLibCells.C
中没有错误,但vobs/ua/HDL/Interface/cli/src/cliSystem.C
中的错误仍然存在。
怎么了?我该怎么做才能消除这个错误?
问题是函数 func
是一个 C 函数,而您尝试从 C++ 函数中调用它。这是有问题的,因为 C++ 做了一些叫做 name mangling 的事情来允许函数重载。
这意味着当您进行声明时
extern void func();
C++ 编译器将破坏 符号,并且将找不到该破坏的符号。
在 C++ 中,您必须禁止对来自 C 对象文件的函数进行名称重整。这是通过特殊的 extern
声明完成的:
extern "C" void func();
稍微相关一点,在 C 中有一个像
这样的声明
void func();
并不意味着该函数不像在 C++ 中那样接受任何参数。在 C 中,该声明意味着 func
接受未指定数量的未指定参数。在 C 语言中,您 必须 使用 void
声明一个不带参数的函数:
void func(void);
C++ 有一个叫做名称重整的东西,所以你可以重载函数。如果您将代码编译为 C++,则声明
extern void func(void);
将在其名称中添加额外的字符来编码它没有参数的事实。您可以通过告诉 C++ 编译器使用 C 约定来禁用它:
extern "C" void func(void);
或
extern "C" {
void func(void);
}
这是正常的,但是将它们放在可以从 C 和 C++ 文件中包含的 header 中:
#if defined __cplusplus
extern "C" {
#endif
void func(void);
// other function declarations
#if defined __cplusplus
}
#endif
我正在对现有的 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,有错误
undefined reference to `func()'
但是对于/vobs/ua/HDL/VHDL/DsnMgr/src/shell.c
,没有错误。
我在 vobs/ua/HDL/Interface/cli/src/cliSystem.C
和 /vobs/ua/HDL/VHDL/lib2v/src/asicLibCells.C
中声明 func
之后,像这样:
extern "C" void func();
/vobs/ua/HDL/VHDL/lib2v/src/asicLibCells.C
中没有错误,但vobs/ua/HDL/Interface/cli/src/cliSystem.C
中的错误仍然存在。
怎么了?我该怎么做才能消除这个错误?
问题是函数 func
是一个 C 函数,而您尝试从 C++ 函数中调用它。这是有问题的,因为 C++ 做了一些叫做 name mangling 的事情来允许函数重载。
这意味着当您进行声明时
extern void func();
C++ 编译器将破坏 符号,并且将找不到该破坏的符号。
在 C++ 中,您必须禁止对来自 C 对象文件的函数进行名称重整。这是通过特殊的 extern
声明完成的:
extern "C" void func();
稍微相关一点,在 C 中有一个像
这样的声明void func();
并不意味着该函数不像在 C++ 中那样接受任何参数。在 C 中,该声明意味着 func
接受未指定数量的未指定参数。在 C 语言中,您 必须 使用 void
声明一个不带参数的函数:
void func(void);
C++ 有一个叫做名称重整的东西,所以你可以重载函数。如果您将代码编译为 C++,则声明
extern void func(void);
将在其名称中添加额外的字符来编码它没有参数的事实。您可以通过告诉 C++ 编译器使用 C 约定来禁用它:
extern "C" void func(void);
或
extern "C" {
void func(void);
}
这是正常的,但是将它们放在可以从 C 和 C++ 文件中包含的 header 中:
#if defined __cplusplus
extern "C" {
#endif
void func(void);
// other function declarations
#if defined __cplusplus
}
#endif