链接错误c和c ++(未定义的引用)

时间:2014-01-22 20:58:30

标签: c++ c linker makefile

abc.c文件

#include "abc.h"
int abc()
{
    return 10;
}

abc.h文件

int abc();

mymain.cpp文件

#include "abc.h"
int main()
{
    abc();
    return  0;
}

生成文件

CC=gcc -O2 
CP=g++

mymain: mymain.o abc.o
    $(CP) -o mymain mymain.o abc.o

mymain.o: mymain.cpp abc.h
    $(CP) -c mymain.cpp abc.h

abc.o: abc.c abc.h
    $(CC) -c abc.c abc.h

clean:  
    $(RM) *.o mymain

输出

g++ -c mymain.cpp abc.h
gcc -O2  -c abc.c abc.h
g++ -o mymain mymain.o abc.o
mymain.o: In function `main':
mymain.cpp:(.text+0x5): undefined reference to `abc()'
collect2: error: ld returned 1 exit status
make: *** [mymain] Error 1

为什么abc()是未定义的引用??

更新

new abc.h

extern "C" {
    int abc();
}

错误

g++ -c mymain.cpp abc.h
gcc -O2  -c abc.c abc.h
In file included from abc.c:1:0:
abc.h:1:8: error: expected identifier or ‘(’ before string constant
 extern "C" {
        ^
abc.h:1:8: error: expected identifier or ‘(’ before string constant
 extern "C" {
        ^
make: *** [abc.o] Error 1

1 个答案:

答案 0 :(得分:7)

问题是你正在尝试将C函数链接到C ++对象,而不告诉编译器这是你正在做的事情。

如果您的头文件(abc.h)如下所示:

extern "C" {
    int abc();
}

它可以工作(当包含在C ++源代码中......但是当包含在C源代码中时会中断)。

您可以将extern "C" {及其尾随}括在宏中,如Combining C++ and C - how does #ifdef __cplusplus work?所示,以便适合包含C和C ++。

请注意,makefile中的$(CP) -c mymain.cpp abc.h没有意义 - 您不希望在编译器命令行中指定标头。这适用于该模式的两种情况。