我有一个依赖于 OpenSSL 的大型 C 文件库,并且我对使用 native 库非常陌生,尤其是对使用 android 很陌生。我已经成功地在 iOS 上实现了这个库,没有出现任何问题。
我一直在网上寻找有关如何执行此操作的教程/信息,但到目前为止我还没有找到任何我能理解的内容。这一切让我很困惑。
本质上,我试图弄清楚如何使用 NDK 将 C 文件库编译为 native 库,并将编译后的库与 imy android 应用程序一起使用。
据我了解,我需要一个适用于 android 本身的自定义 cmake 文件,但我不知道从哪里开始,而且我发现的文档非常难以理解。
所以,我需要一些帮助来理解在以下庄园中编译库的过程:
- 使用 Gradle 和 CMakeLists.txt 编译该库,将其与 openssl 和 libcrypto 链接,并将最终库与我的 Android Studio 项目链接。
- 能够从我的 Java 代码调用这些库中的 native 函数。 (我知道这需要 JNI Java 包装器)
(我已经成功地为 Android 所需的所有架构构建了 libssl 和 libcrypto,但我不确定如何处理 .a
/.so
文件。)
对于此事的任何帮助将不胜感激。
谢谢
编辑:
我成功地使用以下内容生成了一些库文件。
文件结构:
.idea
app
build
gradle
jni <--- I made this folder specifically fo this.
Android.mk <-- This is the important file.
include
openssl
<openssl header files>
libs
arm64-v8a
libcrypto.a
libcrypto.so
libssl.a
libssl.so
armeabi
libcrypto.a
libcrypto.so
libssl.a
libssl.so
armeabi--v7a
libcrypto.a
libcrypto.so
libssl.a
libssl.so
mips
libcrypto.a
libcrypto.so
libssl.a
libssl.so
mips64
libcrypto.a
libcrypto.so
libssl.a
libssl.so
x86
libcrypto.a
libcrypto.so
libssl.a
libssl.so
x86_64
libcrypto.a
libcrypto.so
libssl.a
libssl.so
src <--- These are example files that i used to build this with.
myc_files.c
myother_c_files.c
myc_heades.h
myother_c_headers.h
然后,我在 Android.mk 中使用以下内容,通过运行 ndk-build 来生成一些库。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Select from arm64-v8a armeabi armeabi-v7a mips mips64 x86 x86_64
ARCH := armeabi
APP_UNIFIED_HEADERS := true
#APP_ABI := $(ARCH)
# TARGET_ARCH := $(ARCH)
TARGET_PLATFORM := android-14
SRC_DIR := $(LOCAL_PATH)/src
HDR_DIR := $(LOCAL_PATH)/include
LIB_DIR := $(LOCAL_PATH)/libs
LOCAL_C_INCLUDES := $(HDR_DIR)
LOCAL_MODULE := myclib
LOCAL_SRC_FILES := $(SRC_DIR)/myc_files.c $(SRC_DIR)/myother_c_files.c
LOCAL_LDLIBS += -L$(LIB_DIR)/$(ARCH) -lssl -lcrypto
include $(BUILD_STATIC_LIBRARY)
这些库被放入 PROJECT/obj/local
中,我不知道从这里到哪里,或者 Android.mk 文件是否确实正确构建了库。
最佳答案
更新:使用 AGP 4.0(尚未发布),您可以从 maven 使用 OpenSSL。
dependencies {
implementation "com.android.ndk.thirdparty:openssl:1.1.1d-alpha-1"
}
在 Android.mk 中,您只需添加(在末尾)
$(call import-module, prefab/curl)
以下是完整详细信息:https://android-developers.googleblog.com/2020/02/native-dependencies-in-android-studio-40.html
<小时/>原答案:
0. 为 Android 构建 openssl 库;您必须选择 ABI(armeabi-v7a 和 x86 通常就足够了)。您可以找到official tutorial又长又无聊。在这种情况下,您可以在 GitHub 或其他地方找到预构建的二进制文件。决定您需要共享库还是静态库。
1. 使用 Android Studio 2.3,您可以通过集成的 externalNativeBuild 构建您的库。梯度任务。但您可以使用
ndk-build
单独构建它命令。2.如果您选择不使用 gradle,请将构建的共享库复制到 Android 项目的
app/src/main/jniLibs
目录中。3. 您需要一个 JNI 包装器来将 Java 代码与 C 代码连接起来。在 Java 方面,在一个或多个类中声明必要的 native 方法。这些方法必须在 C/C++ 端实现,如 Android JNI walkthrough 中所述。 。您的 Java 代码必须显式加载包含这些 native 方法实现的共享库。请注意,您无法直接调用库或 opensssl 库中的 native 函数,即使这些函数已导出。
正在运行的Android.mk:
include $(CLEAR_VARS)
LOCAL_MODULE := vrazovpn
LOCAL_SRC_FILES := src/myc_files.c src/myother_c_files.c
LOCAL_STATIC_LIBRARIES := openssl libcrypto
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := openssl
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libssl.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libcrypto
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libcrypto.a
include $(PREBUILT_STATIC_LIBRARY)
一些评论来澄清上述内容:
- LOCAL_SRC_FILES 路径相对于LOCAL_PATH。
- LOCAL_C_INCLUDE 路径是相对于工作目录的,这就是为什么我们经常在它们前面加上
$(LOCAL_PATH)
前缀。 - 可以使用 LOCAL_C_INCLUDES 来引用属于我们使用的某些库的 header ,但使用 的功能将这些 header 与库一起导出会更安全、更简洁LOCAL_EXPORT_C_INCLUDES;还有其他设置可以类似地导出。
Android.mk 不应该(也不能)设置目标 ABI;它从 ndk-build 接收目标 ABI。您可以通过在 Application.mk 文件中或在命令行上列出它们来控制构建中包含哪些 ABI,例如
ndk-build APP_ABI="x86 armeabi-v7a"
如果您在 Android Studio 2.3 或更高版本中使用 gradle 插件构建库,APP_ABI
设置将被忽略。您必须在 abiFilters 中指定列表.
关于android-ndk - 使用Android NDK编译依赖于其他 native 库运行的 native 库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44297396/