首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C++ 链接库顺序导致的符号未定义问题

符号未定义是链接过程中常见的问题,有时候很明显,有时候却很隐晦,比如链接库的顺序导致的符号未定义问题。...问题描述使用 gcc/g++ 编译一个项目的时候,出现了未定义的符号,符号来源于一个开源库,确认了库的位置,库中符号正常定义,库及其路径都被正确的引用了。...链接顺序gcc/g++ 在合并目标文件生成可执行文件的时候会存在库的依赖问题:在命令行中,如果定义一个符号的库出现在引用这个符合的目标文件之前,那么引用就不能被解析,链接会失败。...如果不是相互独立,那么必须对它们进行排序,使得对于每个目标文件的外部引用的符号 s,在命令行中至少有一个 s 的定义是在对 s 的引用之后。...所以 undefined reference to 这个 错误是正常地!

35700

头文件是必须的吗?跟一跟编译过程~~~

): undefined reference to `func()' collect2.exe: error: ld returned 1 exit status 报错说,未定义的引用func()。...上面的ld是链接器,是一个可执行程序,它的输入是一个或多个目标文件,如上面指令中的main.o。 也就是说,目标文件main.o中引用了func(),但链接器找不到它的定义。...显然,main.o中引用但未定义的func()被链接器在func.o中找到了。...即,链接器在面对一个目标文件时,如果碰到里面有未定义的引用,会在其他目标文件中查找,如果找不到,则报错“undefined reference to”。如果找到有且仅有一个,则pass。...本文只是就着这个问题,跟了下编译的过程,看看平常开发过程中遇到的编译报错“未定义的引用”、“未声明的变量”这些错误来源是哪原因是什么。

2.2K10
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    ubuntu gcc编译时对’xxxx’未定义的引用问题

    http://www.cnblogs.com/oloroso/p/4688426.html gcc编译时对’xxxx’未定义的引用问题 原因 解决办法 gcc 依赖顺序问题 在使用gcc编译的时候有时候会碰到这样的问题...本文由乌合之众 lym瞎编,欢迎转载blog.cnblogs.net/oloroso 本文由乌合之众 lym瞎编,欢迎转载 my.oschina.net/oloroso 例如: g++ -o spider...dso.o:在函数‘dso_load(char const*, char const*)’中: dso.cpp:(.text+0x3c):对‘dlopen’未定义的引用 dso.cpp:(.text+0x4c...):对‘dlsym’未定义的引用 dso.cpp:(.text+0xb5):对‘dlerror’未定义的引用 dso.cpp:(.text+0x13e):对‘dlclose’未定义的引用 原因 出现这种情况的原因...但是在链接为可执行文件的时候就必须要具体的实现了。如果错误是未声明的引用,那就是找不到函数的原型,解决办法这里就不细致说了,通常是相关的头文件未包含。

    8.2K20

    C++如何调用写好的C接口?

    + -o main main.cpp test.o 编译后链接出错:main.cpp对print(int, int)未定义的引用。...那么g++编译器为什么找不到print(int,int)呢,其实在我们学C++重载的时候就提到过C++底层的编译原理。...g++ 进行链接,也就是 C++ 链接方式,程序在运行到调用 print 函数的代码时,会在符号表中寻找 _Z5printii(是按照C++的链接方法来寻找的,所以是找 _Z5printii 而不是找...print)的名字,发现找不到,所以会提示“未定义的引用” $ g++ -c test.c $ ls main.cpp makefile test.c test.h test.o $ nm test.o...extern “C” ,这个时候,g++编译器就会按照C语言的链接方式进行寻找,也就是在符号表中寻找print(这才是C++兼容C),这个时候是可以找到的,是不会报错的。

    1.2K10

    Linux命令(63)——nm令

    符号的值表示该符号需要的字节数。例如在一个C文件中,定义int test,并且该符号在别的地方会被引用,则该符号类型即为C,否则其类型为B。...它表示一个符号如果被重定位引用,不会计算该符号的地址,而是必须在运行时计算 N 该符号是一个debugging符号。...对于全局变量来说,在定义它的文件中,其符号类型为B或D,在使用它的文件中,其类型为U。 v,V 该符号是一个弱符号。当弱定义符号与正常定义符号链接时,使用正常定义符号时不会出错。...当弱定义符号与正常定义符号链接时,使用正常定义符号时不会出错。当链接未定义的弱未定义符号时,该符号的值将以系统特定的方式确定,且不会出错。...g++ -c -g test.cpp -o test.o g++ -c -g main.cpp -o main.o 然后通过ar命令将两个目标文件打包成静态库libobjdump.a。

    5.2K00

    严格别名规则“-fstrict-aliasing”和“-fno-strict-aliasing”及类型双关

    下列代码,如果使用“-O2”、“-O3”或“-Os”编译,并且加不“-fno-strict-aliasing”,则“*s”的结果是未定义的,不同的编译器可能产生不同的结果,即使同一编译器也可能运行时结果不尽相同...(&m); printf("%x\n", *s); return 0; } gcc-4.1.2上运行情况,可以看到每次结果都不相同: > g++ --version > g++ -g -o e e.cpp...() { X x; x.m = 0x12345678; short s = x.s; printf("%x\n", s); return 0; } 然而,下列用法仍然是不安全的(多版本gcc实测正常...short s; }; int main() { X x; x.m = 0x12345678; short* s = &x.s; printf("%x\n", *s); return 0; } 下列代码的结果也是未定义的...(多版本gcc实测也正常,同样未有编译告警,但gcc手册指出结果是未定义的): #include union X { int m; short s; }; int main() { int m = 0x12345678

    2K30

    【保姆级教程】Docker服务在双架构(X86和ARM)编译统一实践

    在进行CGO编译时,我们需要考虑多系统多架构的问题,以确保我们的程序可以在不同的操作系统和架构中正常运行。...在进行CGO编译时,我们可以使用交叉编译工具来编译出多个不同操作系统和架构的程序,从而确保我们的程序可以在不同的操作系统和架构中正常运行。...编写Go程序 接下来,我们需要编写一个使用了libcurl库的Go程序。...在程序中,我们使用了CGO LDFLAGS关键字来链接libcurl库,并使用了C语言的头文件来调用libcurl库的函数。 编译ARM架构的程序 接下来,我们需要编译ARM架构的程序。...这些关键字可以让我们在不同的操作系统和架构中使用不同的链接库和编译选项,从而确保我们的程序可以在不同的操作系统和架构中正常运行。 #cgo指令符是用于在Go语言中调用C语言函数和库的关键字。

    1.9K60

    cmake:Windows编译支持HTTPS的curl库及find_package查找CURL时需要注意的问题

    不论是MODULE还是CONFIG模式都能正常找到CURL,你在项目中引用用CURL::libcurl target,能正常编译项目,但如果是要生成动态库或EXE等需要连接的动作时就会报错找不到openssl...正因为如此,要如上优先使用CONFIG模式查找CURL,没找到再用MODULE模式查找,这样就能确保找到CURL::libcurl target可以在项目正常连接。...中的代码片段 # Create imported target CURL::libcurl add_library(CURL::libcurl STATIC IMPORTED) set_target_properties...::Crypto;ZLIB::ZLIB;advapi32;crypt32", 这就是定义了CURL::libcurl的所有依赖库。...并且还通过INTERFACE_COMPILE_DEFINITIONS 属性定义了宏CURL_STATICLIB以告诉引用CURL::libcurl的项目使用的是CURL静态库。

    2K40

    【保姆级教程】Docker服务在双架构(X86和ARM)编译统一实践

    在进行CGO编译时,我们需要考虑多系统多架构的问题,以确保我们的程序可以在不同的操作系统和架构中正常运行。...在进行CGO编译时,我们可以使用交叉编译工具来编译出多个不同操作系统和架构的程序,从而确保我们的程序可以在不同的操作系统和架构中正常运行。...编写Go程序接下来,我们需要编写一个使用了libcurl库的Go程序。...在程序中,我们使用了CGO LDFLAGS关键字来链接libcurl库,并使用了C语言的头文件来调用libcurl库的函数。编译ARM架构的程序接下来,我们需要编译ARM架构的程序。...这些关键字可以让我们在不同的操作系统和架构中使用不同的链接库和编译选项,从而确保我们的程序可以在不同的操作系统和架构中正常运行。图片#cgo指令符是用于在Go语言中调用C语言函数和库的关键字。

    7.6K51

    虚析构函数? vptr? 指针偏移?多态数组? delete 基类指针 内存泄漏?崩溃?

    2、在遇到通过基类指针或引用调用虚函数的语句时,首先根据指针或引用的静态类型来判断所调函数是否属于该class或者它的某个public 基类,如果 属于再进行调用语句的改写: (*(p->_vptr[slotNum...如果不属于,则直接调用指针或引用的静态类型对应的函数,如果此函数不存在,则编译出错。...我们常用的编译器,如vc++、g++等都是用的尾部追加成员的方式实现的继承(前置基类的实现方式),在最好的情况下可以做到指针不偏移;另一些编译器(比如适用于某些嵌入式设备的编译器)是采用后置基类的实现方式...也是论坛上经常讨论的,也就是说delete 基类指针(在指针没有偏离的情况下) 会不会造成内存泄漏的问题,上面说到如果此时基类析构函数为虚函数,那么是不会内存泄漏的,如果不是则行为未定义。.../test )检测,并没有内存泄漏,基类和派生类的析构函数也正常被调用。

    98600

    虚析构函数? vptr? 指针偏移?多态数组? delete 基类指针 内存泄漏?崩溃?

    2、在遇到通过基类指针或引用调用虚函数的语句时,首先根据指针或引用的静态类型来判断所调函数是否属于该class或者它的某个public 基类,如果 属于再进行调用语句的改写: (*(p->_vptr[slotNum...如果不属于,则直接调用指针或引用的静态类型对应的函数,如果此函数不存在,则编译出错。...我们常用的编译器,如vc++、g++等都是用的尾部追加成员的方式实现的继承(前置基类的实现方式),在最好的情况下可以做到指针不偏移;另一些编译器(比如适用于某些嵌入式设备的编译器)是采用后置基类的实现方式...也是论坛上经常讨论的,也就是说delete 基类指针(在指针没有偏离的情况下) 会不会造成内存泄漏的问题,上面说到如果此时基类析构函数为虚函数,那么是不会内存泄漏的,如果不是则行为未定义。.../test )检测,并没有内存泄漏,基类和派生类的析构函数也正常被调用。

    1K20

    centos7环境下ModSecurity-envoy编译和测试(一)-野路子技术宅

    http://www.yousee.top=====================================================================这篇文章是最近2个月的工作成果...最近一年都在参与某央企通信企业的安全产品研发工作,感谢合作方和大佬们给与学习机会,参与云原生、零信任技术和开源安全产品研究工作。...ModSecurity通过插件方式集成到envoy的资料比较少,只好通过各种手段推进工作任务,找同事交流请教、找资料学习和测试,终成本篇的手册。先表个态度:感谢领导,感谢队友,感谢大佬指点和包容。...patchyum -y install patch其他依赖包yum install -y libtool realpath clang-format-5.0 automake yum install -y g+...,保证代码能正常通过和运行,是不严谨和取巧的方式。

    1.9K51

    【深入探索 C++ STL 双端队列 deque】 —— 数据时空的双端虫洞,扭曲常规操作的效率边界

    这些成员类型在实现自定义分配器或理解标准库容器如何与分配器协同工作时非常重要。...Linux下g++的处理方式: 代码编译通过,程序正常运行,但是输出结果错误 输出: Ⅱ、at() 访问元素,返回对deque容器对象中下标为n的元素的引用。...Ⅲ、front() 返回对deque容器中第一个元素的引用。在空容器上调用此函数会导致未定义行为。与operator[]相同,vs下程序崩溃,Linux下g++编译通过,程序输出结果错误!...Ⅳ、back() 访问最后一个元素,返回对容器中最后一个元素的引用。在空容器上调用此函数会导致未定义行为。...当使用已经失效的deque迭代器访问元素时,这是一种未定义行为。g++ 编译器在这种情况下可能没有立即给出错误提示,而是继续执行代码,可能会出现看似 “正确” 的结果。

    21410

    基于腾讯云cos的图床教程

    安装依赖软件COSFS 的编译安装依赖于 automake、git、libcurl-devel、libxml2-devel、fuse-devel、make、openssl-devel 等软件包,Ubuntu...、CentOS、SUSE 和 macOS 的依赖软件安装过程如下:Ubuntu 系统下安装依赖软件:sudo apt-get install automake autotools-dev g++ git...libcurl4-gnutls-dev libfuse-dev libssl-dev libxml2-dev make pkg-config fuseCentOS 系统下安装依赖软件:sudo yum...:sudo zypper install gcc-c++ automake make libcurl-devel libxml2-devel openssl-devel pkg-configmacOS...FUSE 文件系统方式2:umount -l /mnt, 当有程序引用文件系统中文件时,进行卸载不会报错,并在没程序引用时完成卸载 方式3:umount /mnt, 当有程序引用文件系统中的文件时,进行卸载会报错注意

    3.8K31

    蓝桥ROS机器人之C++基础1总结和测评

    语句是一种使程序执行某些操作的指令。语句通常以分号结束。 函数是按顺序执行的语句的集合。每个 C++ 程序都必须包含一个名为main的特殊函数。当运行程序时,执行从main函数的顶部开始。...未赋予值的变量称为未初始化变量。尝试获取未初始化变量的值将导致未定义的行为,这可以通过多种方式表现出来。 C++ 保留了一组称为关键字的名称。这些在语言中具有特殊含义,不能用作变量名。...先让程序运行起来,然后再把它们改进成很棒的东西。 初始化和赋值有什么区别? 初始化为变量提供了一个初始值(在创建时)。 在变量已经定义之后,赋值给变量一个新的值。 什么时候发生未定义的行为?...未定义行为的后果是什么? 未定义的行为发生在程序员执行 C++ 语言未明确规定的事情时。后果几乎可以是任何事情,从崩溃到产生错误的答案再到正常工作。...\n"; return 0; } g++ -std=c++11 ex1.cpp

    1.1K30
    领券