我正在使用 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 的 init
是 zygote
。 Zygote 加载平台版本的 OpenSSL。当 Zygote fork 启动您的应用程序时,您的应用程序将获得已链接的 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 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/