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 将来发生变化,可能会造成混淆。
我在 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 将来发生变化,可能会造成混淆。