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

标签 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");

最佳答案

看来你有两个问题。首先是链接到 OpenSSL;其次是实际在 APK 中查找库。


I am using a C++ library, which is dynamically linked with openss-1.0.1 h libraries...

这是您的第一个问题。 Android 的 initzygote。 Zygote 加载平台版本的 OpenSSL。当 Zygote fork 启动您的应用程序时,您的应用程序将获得已链接的 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 wiki 上 OpenSSL and Android .


"could not find libssl.so.1.0.0 needed by libABC.so"

这是你的第二个问题。首先,如上所述创建一个包装器共享对象。其次,将您的共享对象放在正确的目录中。共享包装器应放在 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和 native 库部分。


 System.loadLibrary("ssl");
 System.loadLibrary("crypto");

相关,libssl依赖于libcrypto,所以应该是:

 static {
     System.loadLibrary("crypto");
     System.loadLibrary("ssl");
 }

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

关于android - 应用程序在加载与 openss-1.0.1h 动态链接的 C++ jni 库时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24424964/

相关文章:

c++ - OpenSSL 证书缺少 key 标识符

java - 输入字符串未知时的字符串分割(Java Android 短信分割转发)

java - Android edittext 带有像cardview一样的阴影

android - NFC P2P as3911 <--> 手机

python - 如何使用 OpenSSL 使用 subjectAltName 和 dirName 生成自签名证书?

openssl - 有人可以使用 OpenSSL AES CCM 给出加密/解密示例吗?

rust - 如何从 C 正确链接到 Rust 动态库?

c++ - 在库中使用全局变量

linux - 像脚本一样调用可执行文件

android - 使用可绘制对象作为侧面图标的复合 EditText