应用程序在加载与openss-1.0.1h动态链接的C ++ jni库时崩溃

时间:2014-06-26 07:41:35

标签: android openssl dynamic-linking

我正在使用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");

1 个答案:

答案 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_methodSSL_CTX_newSSL_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");
 }

但你应该避免它并使用包装器共享对象。