【发布时间】:2017-11-02 00:05:27
【问题描述】:
我有一个依赖于 OpenSSL 的大型 C 文件库,而且我对使用本机库非常陌生,尤其是对使用 android 的新手。我已经成功地在 iOS 上实现了这个库,没有任何问题。
我一直在网上寻找有关如何执行此操作的教程/信息,但到目前为止我还没有找到任何我能理解的东西。这一切都让我很困惑。
基本上我想弄清楚如何使用 NDK 将 C 文件库编译为本机库,并将编译后的库与 imy android 应用程序一起使用。
据我了解,我需要一个用于 android 本身的自定义 cmake 文件,但我不知道从哪里开始,而且我发现的文档非常难以遵循。
所以,我需要一些帮助来理解在以下庄园中编译库的过程:
- 编译库,将其与 openssl 和 libcrypto 链接,使用 Gradle 和 CMakeLists.txt 并将最终库与我的 Android Studio 项目链接。
- 能够从我的 Java 代码调用这些库中的本机函数。 (我知道这需要 JNI Java Wrapper)
(我已经设法为 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 文件是否确实正确构建了这些库。
【问题讨论】:
-
您必须将库构建为共享库,因此将最后一行替换为 include $(BUILD_SHARED_LIBRARY)。其他修复在我更新的答案中。
-
为什么要加C标签?
-
@Stargateur 我正在尝试编译和链接的库是用 C 语言编写的,最终使用的编译器是 GCC 的衍生产品。我链接到我的库的库是用 C 编写的。我的 JNI 包装器将在 C 中。我为什么不添加 C 标记?
-
@NathanFiscaletti C 是关于语言的。如果您对链接器有疑问,这与 C 无关。根据您的逻辑,我们应该为所有内容添加 C 标签,因为 linux、windows 等......都是用 C 编写的。所以一切都是关于 C 的,对吗?这很愚蠢。
-
您可能会对
libcrypto.so和libssl.so感到非常失望。 Zygote 是 Android 的init,将预加载与操作系统打包的 OpenSSL 库的旧版本。您打包的更新版本永远不会加载。您应该使用 OpenSSL wiki 上讨论的 Wrapper Shared Object 技术。
标签: android-ndk openssl android-gradle-plugin