当前位置: 首页 > 知识库问答 >
问题:

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

祁高格
2023-03-14

我有一个测试文件(仅用于链接测试),在该文件中,我用自己的malloc/freelibxmalloc.a重载new/操作符。但是,在链接静态库时,我不断地得到如下“undefined reference to”错误,甚至更改test.o-lxmalloc的顺序。但是与链接这个库的其他C程序相比,一切都工作得很好。我对这个问题很困惑,很感激任何线索。

错误消息:

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
#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;
}
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

共有1个答案

邬弘化
2023-03-14

但是与链接这个库的其他C程序相比,一切都工作得很好。

您是否注意到C和C++编译在对象文件级别上创建了不同的符号名?它被称为“name mangling”。
(C++)链接器会将未定义的引用显示为错误消息中的去角符号,这可能会使您感到困惑。如果使用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
 类似资料:
  • 可能重复: 什么是未定义的引用/未解决的外部符号错误,如何修复? 试图通过 我得到一个错误: main.cpp 搞砸h文件: 有什么想法吗?使用此函数构建具有设置大小的哈希表。 编辑:散列。cpp文件 正在尝试通过以下终端进行编译: g-c Hash.cpp-o Hash. o g-omain.cpphash. o-std=c 0x 不知怎的,它进入了一个无限循环。

  • 可能重复: 什么是未定义的引用/未解决的外部符号错误以及如何修复它? 尝试通过编译我的程序 我得到了错误: 不知怎么会进入一个无限循环。

  • 问题内容: 我试图将静态库(与gcc一起编译)链接到C 程序,但出现了“未定义引用”。我在ubuntu 12.04服务器计算机上使用了gcc和g 版本4.6.3。例如,这是阶乘方法的简单库文件: mylib.h mylib.c 我使用gcc为此mylib.c创建了对象: 再次使用AR实用工具从目标文件创建了静态库: 我用C程序(test.c)和C ++程序(test.cpp)测试了这个库 C和C

  • 问题内容: Java 8之前的Java版本要求本机代码必须位于共享库中,但是我已经读到Java 8可以在JNI中使用静态链接库。我已经搜索了示例,但找不到任何示例。 如何将JNI库静态链接到Java应用程序? 问题答案: Java SE 8规范已更改为支持静态链接,并且静态链接在JDK中实现。在System.loadLibrary的规范中对此进行了简要介绍。它所引用的JNI规范的各个部分在此处和此

  • 问题内容: 我使用的C ++库可以构建为共享库或静态库。该库使用一种工厂技术,该技术在程序启动时创建静态对象并注册静态对象。 只要使用共享库,此方法就可以正常工作。使用静态版本时,所有静态对象都不会包含在最终程序中(因为它们没有被直接引用),因此它们的功能不可用。 有没有一种方法可以在链接时强制gcc包含库中的所有静态对象? 该库是开源的,如果有帮助,我可以对其进行修改。 问题答案: 您可以使用,

  • 问题内容: 我在使用C ++(Eclipse)的Linux中工作,并且想要使用一个库。Eclipse显示了一个错误: 你知道解决方案吗? 这是我的代码: 问题答案: 您必须针对libdl进行链接,添加 -ldl 到您的链接器选项