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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18877437/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:17:03  来源:igfitidea点击:

"undefined reference to" errors when linking static C library with C++ code

c++cstatic-libraries

提问by user2153006

I have a test file (just for the link test) where I overload the new/deleteoperators with my own malloc/freelibrary called libxmalloc.a. But I keep getting "undefined reference to" error as following when linking the static library, even I change the order of test.oand -lxmalloc. But everything works well with other C programs linking this library. I'm so confused with this issue and appreciate any clue.

我有一个测试文件(仅用于链接测试),我使用自己的/库重载new/delete运算符,名为. 但是在链接静态库时,我不断收到“未定义的引用”错误,如下所示,即使我更改了和的顺序。但是一切都与链接此库的其他 C 程序一起运行良好。我对这个问题很困惑,并感谢任何线索。mallocfreelibxmalloc.atest.o-lxmalloc

Error 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

My test.cppfile:

我的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;
}

My Makefile:

我的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

回答by π?ντα ?ε?

But everything works well with other C programs linking this library.

但是一切都与链接此库的其他 C 程序一起运行良好。

Did you notice that C and C++ compilation create different symbol names on object file level? It's called 'name mangling'.
The (C++) linker would show undefined references as demangled symbols in the error message, which might confuse you. If you inspect your test.ofile with nm -uyou'll see that the referenced symbol names don't match with those provided in your library.

您是否注意到 C 和 C++ 编译在目标文件级别创建了不同的符号名称?它被称为“名称修改”。
(C++) 链接器会在错误消息中将未定义的引用显示为乱码符号,这可能会让您感到困惑。如果您检查您的test.o文件,nm -u您会发现引用的符号名称与库中提供的名称不匹配。

If you want to use functions linked in as externals that were compiled using the plain C compiler, you'll need their function declarations enclosed in an extern "C" {}block which suppresses C++ name mangling for everything declared or defined inside, e.g.:

如果您想将链接的函数用作使用普通 C 编译器编译的外部函数,您需要将它们的函数声明包含在一个extern "C" {}块中,该块禁止对内部声明或定义的所有内容进行 C++ 名称修饰,例如:

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

Even better, you might wrap your function declarations in your header files like this:

更好的是,您可以将函数声明包装在头文件中,如下所示:

#if defined (__cplusplus)
extern "C" {
#endif

/*
 * Put plain C function declarations here ...
 */ 

#if defined (__cplusplus)
}
#endif