关于Android 链接库时 undefined reference to 的错误分析

我们在编译Android JNI的时候,经常要链接一些其他的开源库,我搞了几个项目,总是会碰到undefined reference to的问题,而且会重复被一个问题所困扰,浪费了很多宝贵的时间,经过网上的参考,根据自己的项目实践,今天是想彻底解决了这个问题!


一般编译器报 “undefined reference to”的错误是以下几种情况,Android中的makefile是Android.mk命名的。

1 没有指定对应的库(.o/.a/.so) 

使用了库中定义的实体,但没有指定库(-lXXX)或者没有指定库路径(-LYYY),会导致该错误, 

在Android.mk中 用LDFLAGS参数来定义库(-lXXX)和 (-LYYY)的


2 连接库参数的顺序不对 

在默认情况下,对于-l 使用库的要求是越是基础的库越要写在后面,无论是静态还动态 

我在实际使用的过程中,发现-D参数的使用,也会导致undefined reference to”的错误,推荐大家如果想在做宏控制的时候,把-D参数放到最后


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

这个问题与Linux下几乎一样


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

在extern “C”的使用时候,因为我经常需要用JNI链接纯C语言的库,我有时候加上extern "C" 还是不行,后来我才发现,extern "C" 必须要包含了头文件,我在这个问题上纠结了很久,惭愧。


5 运行期报错 

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

关于执行时动态链接的问题,我也碰到过很纠结的情况,就是在Android链接的库依赖于我现在当前的库,就变成了你链接我,我再链接你,导致死都编不过,最好撇清这种关系

展开阅读全文

没有更多推荐了,返回首页