我正在使用C ++库。它与OpenSSL-1.0.1 h库(即libssl.so,libcrypto.so)动态链接,并且预先构建了OpenSSL库。问题是当我尝试使用我的Android应用程序加载库时,应用程序崩溃。在log cat中,我可以看到这样的原因 -
"找不到libABC.so所需的libssl.so.1.0.0"
我还没有为OpenSSL库调用system.loadlibrary(),我只为我的C ++库调用了它。
当我使用OpenSSL-1.0.0的动态链接或OpenSSL-1.0.1h的静态链接时,此问题永远不会起作用。
我不知道如何解决这个问题。任何人都可以帮我解决这个问题吗?
我执行了以下操作来加载库 -
System.loadLibrary("ssl");
System.loadLibrary("crypto");
System.loadLibrary("ABC");
答案 0 :(得分:2)
看起来你有两个问题。首先是与OpenSSL的链接;第二个是在APK中找到图书馆。
我正在使用一个C ++库,它与openss-1.0.1 h库动态链接......
这是你的第一个问题。 Android等同于init
的是zygote
。 Zygote加载平台的OpenSSL版本。当Zygote分支启动你的应用程序时,你的应用程序获得已经链接的OpenSSL版本,可能是0.9.8。由于您的应用程序是针对1.0.1构建的,因此您将在运行时崩溃,因为0.9.8和1.0.0 不二进制兼容。
要解决此问题,您必须构建一个包装器共享对象,该对象链接到OpenSSL库的静态版本。然后,当您需要进行OpenSSL调用时,通过包装器公开它。例如,您可能有GetSslContext
包含对OpenSSL SSLv23_method
,SSL_CTX_new
,SSL_CTX_set_options
等的调用。
这避免了调用Zygote的低级OpenSSL。它还记录在OpenSSL and Android的OpenSSL wiki上。
"找不到libABC.so所需的libssl.so.1.0.0"
这是你的第二个问题。首先,如上所述创建包装器共享对象。其次,将共享对象放在正确的目录中。共享包装器应放在lib/
目录中。我相信你也可以在子目录中拥有该库的专用版本。例如,lib/
将是一个通用的回退,而lib/armv7-a/
将是专为ARMv7a构建的共享对象。
您可以使用ApplicationInfo类及其nativeLibDir方法在运行时找到这些库:
public String nativeLibraryDir
Full path to the directory where native JNI libraries are stored.
另请参阅Android的JNI Tips和本机库部分。
System.loadLibrary("ssl");
System.loadLibrary("crypto");
相关,libssl
取决于libcrypto
,因此它应该是:
static {
System.loadLibrary("crypto");
System.loadLibrary("ssl");
}
但你应该避免它并使用包装器共享对象。