对`func()'的未定义引用

时间:2017-04-21 09:10:38

标签: c linux undefined-reference

我正在对现有的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,没有错误。

我在funcvobs/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中的错误仍然存​​在。

怎么了?如何消除此错误?

2 个答案:

答案 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