Android NDK 在 JNI 中使用来自 C 代码的 .so 库

Android NDK use .so library from c code inside JNI

我在 SO 上发现了类似的问题,但其中 none 的工作流程相同。

我的项目中有一个 .so 库 (libcurl)。该项目已构建,但我需要在 JNI 中的 C 代码中获取 curl.h。

这是我的 Android.mk 文件:

LOCAL_PATH:= $(call my-dir)

LIBS_PATH := libs/$(TARGET_ARCH_ABI)

include $(CLEAR_VARS)
LOCAL_MODULE := libcurl                     
LOCAL_SRC_FILES := $(LIBS_PATH)/libcurl.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := testLib
LOCAL_SRC_FILES := lib.c

LOCAL_SHARED_LIBRARIES += libcurl

include $(BUILD_SHARED_LIBRARY)

这是我的 c class:

#include "curl/curl.h"
#include "lib.h"

JNIEXPORT jint JNICALL Java_com_example_test_1libcurlandroidlib_Lib_getTestNumber
  (JNIEnv *env , jclass clazz)
{
    return 99;
}

问题出在 "curl/curl.h" include 命令。我也尝试过,但它也没有找到它:

jni/lib.c:2:23: fatal error: curl/curl.h: No such file or directory
#include "curl/curl.h"

我的 libcurl.so 文件位于 JNI 文件夹内的 lib 文件夹中,它在构建时将相同的(我认为)文件生成到应用程序根目录下的 libs 文件夹中:

有谁知道为什么我无法获得 curl.h 的引用,或者我必须做什么才能获得这个库?

谢谢!

jni/lib.c:2:23: fatal error: curl/curl.h: No such file or directory

include "curl/curl.h"

要使用这个库,您不仅需要编译后的 .so 文件,还需要头文件通常提供的一组函数原型(可能还有数据类型定义)。

使用定义明确的库安装,这些将在与二进制文件相邻的路径中提供 - 即,您将有一些“curlibrary/lib/libcurl.so”旁边是“curlibrary/include/curl/curl.h

要实现这一点,您可以将 curl 的包含目录的路径添加到您的编译器命令行,大概是通过将其添加到您的 Android.mk

LOCAL_C_INCLUDES := curlibrary/include

或者你把它放在哪里。

要使用包含路径,您在代码中对库的引用需要用尖括号括起来,而不是双引号,即

#include <curl/curl.h>  //this searches the include path

而不是

#include "curl/curl.h"  //while this specifies a location relative to this source file

在更不可靠的情况下您可能没有真正定义明确的安装,而只是一个 .so 文件(希望与您的 Android ABI),以及您已经提取甚至重新创建的头文件。在这种情况下,您可能会更随意地将“curl.h”扔到项目源代码的某个地方,并像您尝试的那样通过特定的引用路径包含它。只要路径正确,它就可以工作 - 但它会破坏清晰的设计层次结构,并且如果 curl 的 api 将来发生变化,可能会造成混淆。