gnetna

做一个有理想的程序员

Java jni 加载 so 时,出现 undefined symbol 错误
1 数据加解密使用了 gmp 大数库,Java 程序通过 Jni 来调用C++接口。

问题描述:

在CentOS环境中,一切正常,Java 程序能正常加载编译后的 so 文件。现在需要将系统建议到麒麟系统上,同样编译出来 .so文件,结果java 程序加载 so 并执行native接口时,报 undefined symbol 错误(注意,找不到的符号是 so 文件依赖的另外的动态库中的函数)。

1 C++验证程序;

首先进行了 c++ 程序验证,写了一个验证程序,通过 lopen 动态加载so文件,程序正常运行。说明能够正确识别所有的函数符号。也说明,库文件本身是没有问题的。

2 ldd 查看

ldd xxx.so发现,依赖库的列表中恰巧缺少了那个包含未定义符号的动态库。推测,很有可能是因为,Java加载动态库时,会根据这些依赖信息进行加载,而c程序的加载机制可能有所不同。

3 ldconfig 

还发现,当执行 ldconfig 时,会报错: libgmp.so.3 不是符号链接!

因为在重新编译生成 libgmp.so.3 时,lib文件并没有放在 /usr/lib 下,然后通过手动拷贝所有 lib 下的文件到 /usr/lib 中。在拷贝的过程中,本来的软连接全部替换成了被链接的文件。

最后,抱着试一试的心态,重新在/usr/lib 下创建相应的软连接,再重新编译生成 so 文件,ldd 查看依赖库时,竟然能正确的显示出依赖 libgmp.so 的信息了。

然后在调用 java 程序,运行正常。

-----------------------------------------
总结:对 so 的版本知识,不够了解,如下:

<以下引用网络资料>
简单可以这样理解,你编译出一个libabc.so,这个东西要这样声明:libabc.so.<major>.<minor>,比如说,你可以有libabc.so.3.2,这是3.2版本的,你还可以再装一个lib.so.4.1的,然后创建一个符号链接libabc.3指向前者,libabc.4指向后者,你的应用程序用3就会用到3,指向4,就会用到前者。

所以,总的来说叫libSM.so.6的,应该是个符号链接,具体是什么版本,你的看你的软件包信息,看你怎么把这个文件装进去的。比如可以考虑用dpkg -S来查一下,有时有些脚本没有写好,链接就会变成文件,你重装(这个包)或者手工修复都可以。

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/antony1776/article/details/51547440
个人分类: Linux 系统
想对作者说点什么? 我来说一句

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

不良信息举报

Java jni 加载 so 时,出现 undefined symbol 错误

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭