undefined reference to异常怎么解决

来自:知识屋    更新日期:早些时候
undefined reference to error解决方法~

Linux下编译程序时,经常会遇到“undefined reference error” 报错,

这里总结一些可能的原因和解决方案,给需要的朋友:

说道undefined reference error,先提一下Linux gcc链接规则:

链接的时候查找顺序是:

-L 指定的路径, 从左到右依次查找
由 环境变量 LIBRARY_PATH 指定的路径,使用":"分割从左到右依次查找
/etc/ld.so.conf 指定的路径顺序
/lib 和 /usr/lib (64位下是/lib64和/usr/lib64)
动态库调用的查找顺序:

ld的-rpath参数指定的路径, 这是写死在代码中的
ld脚本指定的路径
LD_LIBRARY_PATH 指定的路径
/etc/ld.so.conf 指定的路径
/lib和/usr/lib(64位下是/lib64和/usr/lib64)
一般情况链接的时候我们采用-L的方式指定查找路径, 调用动态链接库的时候采用LD_LIBRARY_PATH的方式指定链接路径.

另外注意一个问题,就是只要查找到第一个就会返回,后面的不会再查找. 比如-L./A -L./B -lx 在A中有libx.a B中有libx.a和libx.so, 这个时候会使用在./A的libx.a 而不会遵循动态库优先的原则,因为./A是先找到的,并且没有同名动态库存在

对于动态链接库,实际的符号定位是在运行期进行的.在编译.so的时候,如果没有把它需要的库和他一起进行联编,比如libx.so 需要使用uldict, 但是忘记在编译libx.so的时候加上-luldict的话,在编译libx.so的时候不会报错,因为这个时候libx.so被认为是一个库,它里面存在一些不知道具体实现的符号是合法的,是可以在运行期指定或者编译另外的二进制程序的时候指定.

如果是采用 g++ -Lpath -lx 的方式进行编译,链接器会发现所需要的uldict的符号表找不到从而报错,但是如果是程序采用dlopen的方式载入,由于是运行期,这个程序在这个地方就直接运行报错了.另外还有一种情况就是一个对外的接口在动态库中已经声明定义了,但是忘记实现了,这个时候也会产生类似的错误.

如果在运行期报出这样的错误,就要注意是否是由于某些库没有链接进来或者某些接口没有实现的原因产生

有了上述基础,不难总结出,undefined reference error错误的原因可能来自以下几方面:

1 没有指定对应的库(.o/.a/.so)
使用了库中定义的实体,但没有指定库(-lXXX)或者没有指定库路径(-LYYY),会导致该错误,

2 连接库参数的顺序不对
在默认情况下,对于-l 使用库的要求是越是基础的库越要写在后面,无论是静态还动态

3 gcc/ld 版本不匹配
gcc/ld的版本的兼容性问题,由于gcc2 到 gcc3大版本的兼容性存在问题(其实gcc3.2到3.4也一定程度上存在这样的问题) 当在高版本机器上使用低版本的机器就会导致这样的错误, 这个问题比较常见在32位的环境上, 另外就在32位环境不小心使用了64位的库或者反过来64位环境使用了32位的库.

4 C/C++相互依赖和链接
gcc和g++编译结果的混用需要保证能够extern "C" 两边都可以使用的接口,在我们的64位环境中gcc链接g++的库还需要加上 -lstdc++,具体见前文对于混合编译的说明

5 运行期报错
这个问题基本上是由于程序使用了dlopen方式载入.so, 但.so没有把所有需要的库都链接上,具体参加上文中对于静态库和动态库混合使用的说明

  如何修改游戏?
答:首先,理解修改器工作原理,即根据游戏中数据的变化规律,定位出内存中对应的数据,然后将其修改。然后,查看修改器-菜单- 更多&帮助,里面有多套实例教程。

为什么烧饼修改器在横屏状态下键盘显示不完整?
答:由于手机屏幕分辨率规格众多,不能保证所有屏幕完美适配,烧饼会不断地改进,请尝试下载安装最新版修改器。

什么是root?手机如何获取root?
A:简单地说root就是手机系统的最高管理权限用户是管理员。
依靠第三方root工具,大部分机型都能轻松获取root权限。

手机无法使用烧饼修改器等烧饼系列应用?
答:烧饼修改器需要获取root权限才能正常工作,使用前请确保您的手机已经root,推荐使用PC端一键root工具。

小米手机或刷了MIUI系统设备无法使用烧饼修改器?
答:首先,小米手机或刷了MIUI系统设备需要刷到开发版,取得root权限后才能使用烧饼修改器。其次,请到设置-应用-烧饼修改器 中把“悬浮窗体”的开关打开,结束运行,重启程序后就可以正常使用烧饼修改器了~

小米手机或刷了MIUI系统设备已经刷到开发版,但无法启动烧饼修改器?
答:请检查手机是否屏蔽了“悬浮窗体”。

手机已ROOT,但开启烧饼工具时仍无法获取ROOT权限?
答:解决此办法请按以下步骤依次检查是否能够正常获取root权限:1.重启手机;2.重启修改器;3.手动开启ROOT权限;4.升级更新权限管理软件。
其中,如果是ROOT授权管理工具拒绝了烧饼工具的ROOT权限请求,需要进入ROOT授权管理应用内进行相应设置。

为什么一键修改提示未安装Busybox?
答:请更新到烧饼修改器v2.3以上版本,彻底解决此问题。

烧饼修改器一键修改能还原修改前的数据吗?
答:理论上是可以还原的,但不能百分百保证,请在修改前用第三方备份软件对游戏数据进行适当备份,以防万一。

为什么我已经安装了相应的游戏,但在一键修改中还是提示未安装?
答:由于部分游戏代理渠道不同,其包名包有区别,但烧饼的修改方案只匹配了其中一个包,所以可能会出现上述问题。解决方法为点击一键修改列表中相关的游戏,然后选择“通过市场下载”(前提是你手机安装了应用市场相关的应用,如:豌豆荚、小米商店、当乐游戏中心等),这样下载安装的游戏一般都可以进行修改。

为什么在X86处理器手机和PC端安卓模拟器上,烧饼修改器无法左滑进入加速面板?
答:烧饼修改器暂不支持上述平台的游戏加速,因此屏蔽掉了左滑动作。

为什么强制加速复选框无法勾选?
答:强制加速复选框需要常规加速后才能勾选。

为什么像《神庙逃亡》等3D游戏无法进行加速?
答:请更新到2.5以上版本,修改器加入强制加速引擎,支持加速Unity3D引擎开发的游戏。

烧饼修改器可以修改网游吗?
答:不能。由于网游的数据是和服务器端同步的,而修改器修改的都是本地数据,修改后的数据上传服务器过程中会有验证,一但发现异常便会直接反馈数据无效,因此修改失败。但不排除部分网游存在BUG,可以通过特殊方法修改成功,但烧饼哥不建议大家修改网游。

为什么一些新版本的单机游戏无法修改?
答:首先,不是所有游戏都能修改。其次,游戏更新版本后,可能会修复旧版的漏洞,甚至加上一些保护措施。对于这种情况,请关注烧饼修改器后续新功能。

为什么GBA等模拟器游戏改不了数据?
答:请点击修改器输入框左侧类似“放大镜”样式的图标,选择“深度搜索”便可以尝试修改模拟器游戏了。

安装了烧饼工具箱为什么无法直接卸载?改如何卸载?
因为其中锁屏功能需要激活手机系统设备管理器,一旦激活之后,Android4.0以下设备就会出现无法直接卸载的小问题。
解决方法:
方法一:进入烧饼工具箱-设置- 卸载(在最底部)。
方法二:进入手机-系统设置-安全和隐私-设备管理器-去掉烧饼工具箱的√,ok,现在就能正常卸载了。
为什么锁屏以后屏幕又亮了?
这个现象是Android4.0以上设备才有的问题,关闭屏幕电源涉及到root权限,请到游戏大师-设置-插件设置-锁屏-开启root锁屏。
为什么打开移动数据网络后,跳转到网络设置?
这个现象是Android4.0以下设备才有的问题,同样以后加上root权限后就能解决这个问题。

这是个编程链接错误,意思是说在你的程序里引用了某个函数或变量, 但是链接器找不到该变量的定义.

(1)如果报的符号是在某个第三方库里的, 比如uuid的什么什么函数, 则要检查你的libqte是不是编译得正确. 本来这些库应该正确链接到libqte.so上, 这样在qtopia链接的时候就不需要显式的加上这些库了. 

有的时候libqte没有正确链接好, 但是在编译libqte阶段不会报错, 到后面qtopia或者其他应用编译的时候就出错了.


(2)把报错的库删除, 重新编译库. 如果是libqte, 要把你环境里的出现libqte的地方都检查检查, 有可能存在不同的libqte互相影响.

扩展资料:

程序错误类型

程序错误类型主要有语法错误、语义错误和逻辑错误,其中,语法错误和逻辑错误能通过编译器发现.

(1)语法错误

语法错误是因为源程序中不正确的代码产生的,即在编写程序时没有遵守语法(或词法)规则,书写了错误的语法代码,从而导致编译器无法正确解释源代码而产生的错误,通常是由于录入的错误引起的,它在词法分析或语法分析时检测出来。

(2)语义错误

语义错误是指源程序中不符合语义规则的错误,即一条语句试图执行一条不可能执行的操作而产生的错误。语义错误有的在语义分析时检测处来,有的在运行时才能检测出来。如变量声明错误、作用域错误、数据存储区的溢出等错误。

(3)逻辑错误

逻辑错误是指程序的运行结果和程序员的设想有出入时产生的错误。这类错误并不直接导致程序在编译期间和运行期间出现错误,但是程序未按预期方式执行,产生了不正确的运行结果,较难发现。这种错误只能通过分析结果,将结果与设计方案进行对比来发现。

参考资料:百度百科-错误处理



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

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

    测试代码如下:

 

    然后编译。

gcc -c test.c  gcc –c main.c 

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

gcc -o main main.o 

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

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

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

gcc -o main main.o test.o 

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

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

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

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

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

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

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

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

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

gcc -c main.c 

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

gcc -o main main.o 

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

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

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

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

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

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文件。

gcc -c func.c  gcc -c test.c  gcc -c main.c 

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

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

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

gcc -o main main.o test.a 

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

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

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

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

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

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

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

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

    我们会得到如下报错.

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

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

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

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

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

  

 

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

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

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

    

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

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

    会发现报错:

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

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

    

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

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



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

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

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

3.gcc -o main main.o这时,你会发现,报错了:

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

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



在你的操作系统中出现了这样的一场,就是在告诉你,你的系统与一些软件不兼容,需要你找到另外的软件做代替。

看下是不是有宏将其屏蔽了


undefined reference to异常怎么解决视频

相关评论:

相关主题精彩

版权声明:本网站为非赢利性站点,内容来自于网络投稿和网络,若有相关事宜,请联系管理员

Copyright © 喜物网