链接静态C库与C ++代码时出现“未定义的引用”错误

我有一个testing文件(仅用于链接testing),我用我自己的malloc / free库libxmalloc.a重载了新的/删除操作符。 但是当我连接静态库的时候,我总是收到“underdefined reference to”错误,即使我改变了test.o和-lxmalloc的顺序。 但是,其他C程序连接这个库一切正常。 我很困惑这个问题,并感谢任何线索。

错误MSG:

g++ -m64 -O3 -I/usr/include/ethos -I/usr/include/nacl/x86_64 -c -o test.o test.cpp g++ -m64 -O3 -L. -o demo test.o -lxmalloc test.o: In function `operator new(unsigned long)': test.cpp:(.text+0x1): undefined reference to `malloc(unsigned long)' test.o: In function `operator delete(void*)': test.cpp:(.text+0x11): undefined reference to `free(void*)' test.o: In function `operator new[](unsigned long)': test.cpp:(.text+0x21): undefined reference to `malloc(unsigned long)' test.o: In function `operator delete[](void*)': test.cpp:(.text+0x31): undefined reference to `free(void*)' test.o: In function `main': test.cpp:(.text.startup+0xc): undefined reference to `malloc(unsigned long)' test.cpp:(.text.startup+0x19): undefined reference to `malloc(unsigned long)' test.cpp:(.text.startup+0x24): undefined reference to `free(void*)' test.cpp:(.text.startup+0x31): undefined reference to `free(void*)' collect2: ld returned 1 exit status make: *** [demo] Error 1 

我的test.cpp文件:

 #include <dual/xalloc.h> #include <dual/xmalloc.h> void* operator new (size_t sz) { return malloc(sz); } void operator delete (void *ptr) { free(ptr); } void* operator new[] (size_t sz) { return malloc(sz); } void operator delete[] (void *ptr) { free(ptr); } int main(void) { int *iP = new int; int *aP = new int[3]; delete iP; delete[] aP; return 0; } 

我的Makefile:

 CFLAGS += -m64 -O3 -I/usr/include/ethos -I/usr/include/nacl/x86_64 CXXFLAGS += -m64 -O3 LIBDIR += -L. LIBS += -lxmalloc all: demo demo: test.o $(CXX) $(CXXFLAGS) $(LIBDIR) -o demo test.o $(LIBS) test.o: test.cpp $(CXX) $(CFLAGS) -c -o $@ $< clean: - rm -f *.o demo 

但是,其他C程序连接这个库一切正常。

您是否注意到C和C ++编译在对象文件级别创build不同的符号名称? 这就是所谓的“ 名称捣毁 ”。
(C ++)链接器会在错误消息中显示未定义的引用作为demangled符号,这可能会使您感到困惑。 如果你用nm -u检查你的test.o文件,你会发现引用的符号名称与库中提供的符号名称不匹配。

如果要使用作为外部函数链接的函数,使用普通的C编译器进行编译,则需要使用extern "C" {}块中的函数声明,该函数声明禁止C ++名称在内部声明或定义的所有内容,例如:

 extern "C" { #include <dual/xalloc.h> #include <dual/xmalloc.h> } 

更好的是,你可能把你的函数声明包装在你的头文件中,如下所示:

 #if defined (__cplusplus) extern "C" { #endif /* * Put plain C function declarations here ... */ #if defined (__cplusplus) } #endif