动态调用 openssl 库时报错:
java.lang.UnsatisfiedLinkError: dlopen failed: library "libcrypto.so.1.0.0" not found
at java.lang.Runtime.loadLibrary(Runtime.java:372)
at java.lang.System.loadLibrary(System.java:1076)
at com.example.blt.testjniopenssl.OpensslJni.<clinit>(OpensslJni.java:10)
at com.example.blt.testjniopenssl.MainActivity.onCreate(MainActivity.java:29)
at android.app.Activity.performCreate(Activity.java:6904)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1136)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3266)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3415)
at android.app.ActivityThread.access$1100(ActivityThread.java:229)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1821)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7325)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1321)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1211)
原因
安卓对带版本号的 so 没有支持
解决方案
-
mac 中可以使用 rpl 工具修改字符串
rpl -R -e .so.1.1 "1_1_so" libcrypto.so rpl -R -e .so.1.1 "1_1_so" libssl.so
Java加载代码变为:
static { System.loadLibrary("crypto_1_1"); System.loadLibrary("ssl_1_1"); System.loadLibrary("gmssljni"); }
-
重新编译 libcrypto.so 和 libssl.so 生成不带版本号的 so
打开 openssl 源码,Configurations/15-android.conf,在第 173 行增加
shared_extension => ".\$(SHLIB_VERSION_NUMBER).so"
修改完成后如下所示:
"android" => { inherit_from => [ "linux-generic32" ], template => 1, cflags => add(sub { android_ndk()->{cflags} }), cppflags => add(sub { android_ndk()->{cppflags} }), cxxflags => add(sub { android_ndk()->{cflags} }), bn_ops => sub { android_ndk()->{bn_ops} }, bin_cflags => "-pie", enable => [ ], # 重定义`shared_extension`, 修改生成的so名字 shared_extension => ".\$(SHLIB_VERSION_NUMBER).so", },
参考:
GmSSL: java.lang.UnsatisfiedLinkError: dlopen failed: library “libcrypto.so.1.1” not found