关于"undefined reference to" 问题的原因和解决办法

2023-05-16

  最近在Linux下编程发现一个诡异的现象,就是在链接一个静态库的时候总是报错,类似下面这样的错误:

  
  
  1. (.text+0x13): undefined reference to `func' 

    关于undefined reference这样的问题,大家其实经常会遇到,在此,我以详细地示例给出常见错误的各种原因以及解决方法,希望对初学者有所帮助。

1.  链接时缺失了相关目标文件(.o)

    测试代码如下:

 

    然后编译。


  
  
  1. gcc -c test.c  
  2. gcc –c main.c 

    得到两个 .o 文件,一个是 main.o,一个是 test.o ,然后我们链接 .o 得到可执行程序:


  
  
  1. gcc -o main main.o 

    这时,你会发现,报错了:


  
  
  1. main.o: In function `main':  
  2. main.c:(.text+0x7): undefined reference to `test'  
  3. collect2: ld returned 1 exit status 

    这就是最典型的undefined reference错误,因为在链接时发现找不到某个函数的实现文件,本例中test.o文件中包含了test()函数的实现,所以如果按下面这种方式链接就没事了。


  
  
  1. gcc -o main main.o test.o 

   【扩展】:其实上面为了让大家更加清楚底层原因,我把编译链接分开了,下面这样编译也会报undefined reference错,其实底层原因与上面是一样的。


  
  
  1. gcc -o main main.c //缺少test()的实现文件 

需要改成如下形式才能成功,将test()函数的实现文件一起编译。


  
  
  1. gcc -o main main.c test.c //ok,没问题了 

2.    链接时缺少相关的库文件(.a/.so)

    在此,只举个静态库的例子,假设源码如下。

    先把test.c编译成静态库(.a)文件


  
  
  1. gcc -c test.c  
  2. ar -rc test.a test.o 

    至此,我们得到了test.a文件。我们开始编译main.c


  
  
  1. gcc -c main.c 

    这时,则生成了main.o文件,然后我们再通过如下命令进行链接希望得到可执行程序。


  
  
  1. gcc -o main main.o 

    你会发现,编译器报错了:


  
  
  1. /tmp/ccCPA13l.o: In function `main':  
  2. main.c:(.text+0x7): undefined reference to `test'  
  3. collect2: ld returned 1 exit status 

    其根本原因也是找不到test()函数的实现文件,由于该test()函数的实现在test.a这个静态库中的,故在链接的时候需要在其后加入test.a这个库,链接命令修改为如下形式即可。


  
  
  1. gcc -o main main.o ./test.a  //注:./ 是给出了test.a的路径 

     【扩展】:同样,为了把问题说清楚,上面我们把代码的编译链接分开了,如果希望一次性生成可执行程序,则可以对main.c和test.a执行如下命令。


  
  
  1. gcc -o main main.c ./test.a  //同样,如果不加test.a也会报错 

3.    链接的库文件中又使用了另一个库文件

    这种问题比较隐蔽,也是我最近遇到的与网上大家讨论的不同的问题,举例说明如下,首先,还是看看测试代码。

    从上图可以看出,main.c调用了test.c的函数,test.c中又调用了fun.c的函数。
    首先,我们先对fun.c,test.c,main.c进行编译,生成 .o文件。


  
  
  1. gcc -c func.c  
  2. gcc -c test.c  
  3. gcc -c main.c 

    然后,将test.c和func.c各自打包成为静态库文件。


  
  
  1. ar –rc func.a func.o  
  2. ar –rc test.a test.o 

    这时,我们准备将main.o链接为可执行程序,由于我们的main.c中包含了对test()的调用,因此,应该在链接时将test.a作为我们的库文件,链接命令如下。


  
  
  1. gcc -o main main.o test.a 

    这时,编译器仍然会报错,如下:


  
  
  1. test.a(test.o): In function `test':  
  2. test.c:(.text+0x13): undefined reference to `func'  
  3. collect2: ld returned 1 exit status 

    就是说,链接的时候,发现我们的test.a调用了func()函数,找不到对应的实现。由此我们发现,原来我们还需要将test.a所引用到的库文件也加进来才能成功链接,因此命令如下。


  
  
  1. gcc -o main main.o test.a func.a 

    ok,这样就可以成功得到最终的程序了。同样,如果我们的库或者程序中引用了第三方库(如pthread.a)则同样在链接的时候需要给出第三方库的路径和库文件,否则就会得到undefined reference的错误。

4 多个库文件链接顺序问题

    这种问题也非常的隐蔽,不仔细研究你可能会感到非常地莫名其妙。我们依然回到第3小节所讨论的问题中,在最后,如果我们把链接的库的顺序换一下,看看会发生什么结果?


  
  
  1. gcc -o main main.o func.a test.a 

    我们会得到如下报错.


  
  
  1. test.a(test.o): In function `test':  
  2. test.c:(.text+0x13): undefined reference to `func'  
  3. collect2: ld returned 1 exit status 

    因此,我们需要注意,在链接命令中给出所依赖的库时,需要注意库之间的依赖顺序,依赖其他库的库一定要放到被依赖库的前面,这样才能真正避免undefined reference的错误,完成编译链接。

5. 在c++代码中链接c语言的库

    如果你的库文件由c代码生成的,则在c++代码中链接库中的函数时,也会碰到undefined reference的问题。下面举例说明。

    首先,编写c语言版库文件: 

    

    编译,打包为静态库:test.a


  
  
  1. gcc -c test.c  
  2. ar -rc test.a test.o 

    至此,我们得到了test.a文件。下面我们开始编写c++文件main.cpp

    

    然后编译main.cpp生成可执行程序:


  
  
  1. g++ -o main main.cpp test.a 

    会发现报错:


  
  
  1. /tmp/ccJjiCoS.o: In function `main': 
  2. main.cpp:(.text+0x7): undefined reference to `test()' 
  3. collect2: ld returned 1 exit status 

    原因就是main.cpp为c++代码,调用了c语言库的函数,因此链接的时候找不到,解决方法:即在main.cpp中,把与c语言库test.a相关的头文件包含添加一个extern "C"的声明即可。例如,修改后的main.cpp如下:

    


  
  
  1. g++ -o main main.cpp test.a 

    再编译会发现,问题已经成功解决。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于"undefined reference to" 问题的原因和解决办法 的相关文章

  • C# 如何根据对象引用计算哈希码

    各位 这里有一个棘手的问题摆在你们面前 TickZoom 系统的一部分必须将每种类型的对象的实例收集到 Dictionary 类型中 它们的相等性和哈希码必须基于对象的实例 这意味着引用相等而不是值相等 挑战在于系统中的一些对象已经重写了
  • 如何在C++中“返回一个对象”?

    我知道这个标题听起来很熟悉 因为有很多类似的问题 但我要求问题的不同方面 我知道将东西放在堆栈上和将它们放在堆上之间的区别 在Java中我总是可以返回对 本地 对象的引用 public Thing calculateThing Thing
  • Google 关于输入/输出参数作为指针的样式指南

    The 谷歌 C 风格指南 http google styleguide googlecode com svn trunk cppguide html做出了明确的区分 严格遵循cplint py http google styleguide
  • 既然 C++ 具有 const 引用,为什么我应该按值返回某些内容?

    考虑这个函数 Thing func return something 每次调用此函数时 都会生成一个副本something被创建并传递给调用者 我的问题是 为什么不这样做 every我想按值返回一些东西 const Thing func r
  • 在 C# 中调用 F# dll

    如何创建 F dll 并在 C 中调用它 谢谢 要在 F 中创建 DLL 您应该在项目属性中将输出类型设置为类库 使用前面提到的 添加引用 对话框在 C 项目中添加引用
  • Swift 使用 UnsafePointer 从 UnsafeMutablePointer 获取值

    我正在努力通过contextInfo of typeUnsafeMutablePointer
  • JavaScript 通过引用与通过值 [重复]

    这个问题在这里已经有答案了 我正在寻找一些很好的综合阅读材料 了解 JavaScript 何时按值传递内容 何时通过引用传递内容 何时修改传递的项目影响函数外部的值以及何时不影响函数外部的值 我还感兴趣的是 何时通过引用与通过值分配给另一个
  • “基础 - ReferenceError:启动基础 zurb 项目时未定义原始值。”

    创建 Foundation Zurb 项目时出现错误 尝试使用之前针对其他应用程序显示的建议来解决问题 但没有一个有效 一篇文章引用了更新 elm 我这样做了 但是 它不起作用 此外 我查看了 Gulp 3 的已关闭问题 我正在使用 gul
  • 如何在结构字段上创建可变迭代器

    所以我正在使用 Rust 开发一个小型 NES 模拟器 并且我正在尝试使用我的状态寄存器 寄存器是一个结构体 其中包含一些包含布尔值的字段 标志 寄存器本身是 CPU 结构体的一部分 现在 我想循环这些字段并根据我执行的某些指令设置布尔值
  • python numpy 和内存效率(通过引用传递与值传递)

    我最近越来越多地使用 python 来代替 c c 因为它使我的编码时间缩短了几倍 同时 当我处理大量数据时 我的python程序运行速度开始变得比c中慢很多 我想知道这是否是由于我使用大型对象 数组效率低下所致 有没有关于 numpy p
  • 如何创建匹配键的查询?

    我使用另一个用户 赞助商 的密钥来指示谁是用户的赞助商 它会在数据存储中为那些拥有赞助商的用户创建一个链接 最多可以是一个 但赞助商可以赞助许多用户 例如在本例中 ID 2002 赞助了另外三个用户 在这种情况下 这个查询做了我想要的 SE
  • 为什么我不能在 C++ 中的 `std::map` 中存储引用?

    我知道引用不是指针 而是对象的别名 但是 我仍然不明白这对我作为程序员到底意味着什么 即幕后的引用是什么 我认为理解这一点的最好方法是理解为什么我无法在地图中存储参考 我知道我需要停止将引用视为指针的语法糖 只是不知道如何 按照我的理解 引
  • 使用 C# 访问 Sharepoint - 在哪里可以找到参考库?

    我目前正在用 C 编写一个 Windows 应用程序 它将向文档库列表添加文档 我试图引用 Microsoft Sharepoint 但是我没有看到 Visual Studio 2005 添加引用列表中的 COM 或 NET 库 我需要引用
  • Firefox 中的 JavaScript 错误

    我在 Firefox 中运行 JavaScript 时遇到问题 下面的脚本在除 Firefox 之外的其他浏览器中运行没有问题 var vars hash var hashes window location href slice wind
  • 的 xml 问题

    我有一个 xml 架构
  • 如何使用程序集绑定重定向来忽略修订号和内部版本号

    我有几个 C NET 应用程序 以及供它们访问数据库的 API 我想将 API 的所有版本放入数据库中 并让它们选择最高版本和内部版本号 但坚持使用它们构建时使用的主要版本号和次要版本号 基本上当我参考API时1 2 3 4我想要参考阅读1
  • 通过引用调用原型函数时,类失去“this”范围

    谁能向我解释为什么 b 返回未定义以及如何解决这个问题 当我通过引用调用原型函数时 为什么 this 范围会丢失 MyClass function test this test test MyClass prototype myfunc f
  • 每次加载解决方案时,所有项目引用都有黄色三角形

    我的所有项目 来自同一解决方案 引用都标有黄色三角形 这些项目都设置为相同的 NET 版本 4 5 1 错误日志说 无法引用项目 CommonLibrary 暂时解决该问题的方法是 删除并重新添加引用 右键单击并选择 添加服务引用 并立即取
  • 这段C++代码是如何工作的?

    我在 Geek For Geeks 中看到了下面的例子 include
  • ^ 和 _ 宏之后出现的数字(是:LaTeX 限制?)

    我在 LaTeX 中遇到了一个恼人的问题 我有一个大约 1000 行的 tex 文件 我已经有了一些数字 但是当我尝试添加另一个数字时 它会吐出 Undefined control sequence

随机推荐

  • 2012年展望

    由于各种原因 xff0c 客观的 主观的 不过归根结底还是主观的多一些 xff0c 2011年整体过的很颓废 xff0c 上班大多在上网 xff0c 工作上几乎没有一点成绩 xff0c 自己也是很不满意 2012年世界末日都快来了 xff0
  • http和ftp协议的区别

    项目中应用到ftp xff0c 将ftp的笔记上传一下 简单的说 xff1a HTTP是超文本传输协议 xff1b 面向网页的 FTP是File Transfer Protocol 文件传输协议 xff1b 面向文件的 1 FTP 1 FT
  • Python爬虫(4)获得所有Top250部电影的信息并存入数据库

    上次我们完成了单页电影的获取并保存到了Excel文件中 xff0c 不知道小伙伴们都完成了没 xff1f 有没有把Top250部电影都保存下来的 xff1f 在编写这些代码过程中遇到什么问题了没 xff1f 如果遇到但是没有解决 xff0c
  • c#笔记-模式匹配

    模式匹配 模式匹配可以判断一个值的类型和内容 可以判断嵌套的属性 xff0c 但只能和常量进行比较 模式匹配使用is表达式 xff0c 或是在switch选择 xff0c 和switch表达式的分支块中启用 模式匹配使用专有的关键字或运算符
  • typeScript+egg.js+node.js后台项目搭建(一)

    typeScript egg js node js后台项目搭建 一 1 安装node js 地址 https nodejs org en 下载安装后 打开控制台cmd 输入 node v 在安装ts 可以参考typeScript中文官网 n
  • CGroup 介绍、应用实例及原理描述(已发表于IBM开发者论坛)

    插播小广告 xff0c 本人的 大话 Java性能优化 一书已经在亚马逊 京东 当当 天猫出售 xff0c 提前谢谢大家支持 原文请查看 xff1a http www ibm com developerworks cn linux 1506
  • python + celery简例

    在网上找了半天 xff0c 也没找到完整的例子 xff0c 自己写吧 1 一个队列 自定义10个优先级 xff0c 修改默认celery队列名称 1 testcelery py from celery import Celery impor
  • java+selenium获取动态下拉列表元素

    做自动化的时候 xff0c 遇到这么一个闹心问题 xff1a 研发用html里的 lt div input gt 方式 xff0c 所以无法使用select获取列表元素 原本使用Robot也可以定位 xff0c 但是headless模式 x
  • Redis安装和配置

    网上有海量的Redis文章 xff0c 写的都很详细 这里就是简单记录一下自己查aof问题过程中遇到的问题 xff0c 主要是aof文件所在目录在redis conf里的位置 1 在ubuntu16上安装Redis sudo apt get
  • mysql 主从部署

    在ubuntu 16上 xff0c 配置mysql 主从服务器 查看mysql主从命令 show variables like 39 server id 39 show variables like 39 log bin 39 show m
  • 编写的windows程序,崩溃时产生crash dump文件的办法 .

    一 引言 dump文件是C 43 43 程序发生异常时 xff0c 保存当时程序运行状态的文件 xff0c 是调试异常程序重要的方法 xff0c 所以程序崩溃时 xff0c 除了日志文件 xff0c dump文件便成了我们查找错误的最后一根
  • 网络性能测试工具iperf详细使用图文教程

    Iperf是一个网络性能测试工具 Iperf可以测试TCP和UDP带宽质量 Iperf可以测量最大TCP带宽 xff0c 具有多种参数和UDP特性 Iperf可以报告带宽 xff0c 延迟抖动和数据包丢失 利用Iperf这一特性 xff0c
  • 使用Klockwork进行代码分析简单操作流程

    前一段时间公司试用了一下klockwork公司的klockwork代码静态分析软件 xff0c 我所在项目组进行了试点 xff0c 试用后感觉不错 xff0c 有几大亮点 xff1a 1 xff09 对代码进行静态分析 xff0c 无需改动
  • C++特性:多态、重写

    说一下多态 多态就是不同的继承类对象 xff0c 针对同一消息做出不同的响应 xff0c 父类的指针指向或者绑定到子类的对象 xff0c 使得父类指针呈现多种不同的表现方式 要实现多态 xff0c 首先父类需要有一个virtual修饰的虚方
  • Jmeter(三)-简单的HTTP请求(参数化)

    xfeff xfeff 首先建立一个线程组 xff08 Thread Group xff09 xff0c 为什么所有的请求都要加入线程组这个组件呢 xff1f 不加不行吗 xff1f 答案当然是不行的 因为jmeter的所有任务都必须由线程
  • no suitable driver found for jdbc:mysql//localhost:3306/..

    xfeff xfeff 出现这样的情况 xff0c 一般有四种原因 xff1a 一 xff1a 连接URL格式出现了问题 Connection conn 61 DriverManager getConnection 34 jdbc mysq
  • java模拟键盘按键

    xfeff xfeff come from http bbs 51cto com thread 1097189 1 html 功能描述 1 打开一个记事本 2 最大化 3 模拟按键操作 现 贴出 源码 xff1a 预览源代码 打印 001i
  • Android手机通过USB数据线共享Linux电脑网络

    这里要讲述的是手机通过usb数据线共享电脑 xff08 linux系统 xff09 的网络来自由上网 通过USB数据线将手机与电脑相连 再分别在电脑和手机上虚拟出一个网络接口用于网络通信 这很类似于VPN与虚拟机上网的原理 好处是不论台式还
  • CentOS时间的查看与修改

    http www centoscn com CentOS help 2014 0805 3430 html 1 查看 修改Linux时区与时间 一 linux时区的查看与修改 1 xff0c 查看当前时区 date R 2 xff0c 修改
  • 关于"undefined reference to" 问题的原因和解决办法

    最近在Linux下编程发现一个诡异的现象 xff0c 就是在链接一个静态库的时候总是报错 xff0c 类似下面这样的错误 xff1a text 43 0x13 undefined reference to 96 func 39 关于unde