前几天调试安卓下某个应用程序的加密功能,需要依赖openssl库,由于编译制定了连接libssl.so.xxx,但是没有指定完整路径,结果发现这个应用程序没有起来,通过调试发现,程序起来的时候提示找不到SSL_xxx函数,但是通过arm-linux-androideabi-nm libssl.so.1.x.x | grep SSL_xxx
000390bc T SSL_xxx,发现动态库里面有这个SSL_xxx函数,然而怀疑是不是安卓设备里面的libssl.so.1.x.x动态库,跟应用程序实际编译链接时的libssl.so.1.x.x动态库不是同一个动态库,然后想到通过md5计算下这两个动态库是不是同一个动态库,md5sum libssl.so.1.x.x后,发现两边的这个动态库的md5值是一样的,说明动态库是一样的,即动态库没有问题。
查看安卓的动态库目录下,有两个libssl打头的动态库,其中一个就是我们应用程序需要用到的libssl.so.1.x.x,结合调试应用程序启动失败的打印信息,虽然应用打印提示链接的动态库是libssl.so.1.x.x,但是后面又提示找不到 SSL_xxx函数,怀疑程序实际运行时实际链接的动态库用的是libssl打头的另外一个动态库,为了验证这种猜想,重新修改了Makefile,编译连接时显示指定了openssl库的路径及链接库,重新编译后,应用程序替换到安卓设备上后,发现可以正常运行起来,也证明了自己的猜想。
做过跨平台程序的同学,应该清楚,Windows平台下编译程序,链接动态库时,需要显示指定所链接动态库的路径;而Linux平台下则不需要,链接时系统会自动查找(需要注意一点,当系统下有不同版本的某个动态库,比如:依赖的A库依赖动态库libxxx.so.0,依赖的B库依赖动态库libxxx.so.1,这时需要注意应用程序链接A库和B库的顺序,那个在前那个在后,编译时可能需要调整链接库的顺序,否则可能会遇到编译失败的问题);安卓环境感觉是介于Windows和Linux之间,编译链接程序时,需要注意下,可能遇到笔者的情形。