2014-01-22 210 views
2

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()是未定义的引用?链接错误C和C++(未定义参考)

UPDATE

新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 
+2

不要将'abc.h'传递给编译器。头文件在被'.c'或'.cpp'文件'#include'ed处理时被处理。 –

+2

另外,'CP'对此是一个非常糟糕的名字。大多数人会认为你正在试图复制一个文件。 make for C++编译器中的默认变量名是'CXX'(和'CXXFLAGS'用于C++编译器特定的标志)。 – MadScientist

回答

6

问题是你想一个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没有任何意义 - 您不希望在编译器命令行中指定标头。这适用于这种模式的两种情况。

+0

+1!现在我终于知道'extern“C”'是什么意思了,我甚至没有必要google! – BWG

+0

@mah感谢您快速回答。我收到另一个错误。我已经更新了这个问题。 – shantanu

+0

@shantanu编译.c文件时需要有条件地排除它,因为C编译器不知道'extern“C”' – JustSid