我遇到了使用Android NDK r8b在我的Android项目中链接C库的问题。 我用ARM的工具链构建了cURL库(没有SSL),它为我提供了一个libcurl.a文件和一个libcurl.so.4.2.0文件。 我还创建了一个C文件来为我的Java代码提供函数并使用cURL库。
Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= libcurl
LOCAL_SRC_FILES := libcurl.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := curljni
LOCAL_SRC_FILES := curljni.c
LOCAL_STATIC_LIBRARIES := libcurl
include $(BUILD_SHARED_LIBRARY)
现在我的 C档
#include <string.h>
#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
jstring Java_test_curljni_MainActivity_stringFromJNI(JNIEnv* env, jobject thiz)
{
CURL *curl;
CURLcode
......
}
当我尝试使用项目文件夹中的ndk-build命令构建时,这是输出错误:
Compile thumb : curljni <= curljni.c
jni/curljni.c: In function 'Java_test_curljni_MainActivity_stringFromJNI':
jni/curljni.c:8:3: error: unknown type name 'CURL'
jni/curljni.c:9:3: error: unknown type name 'CURLcode'
jni/curljni.c:11:8: warning: assignment makes pointer from integer without a cast [enabled by default]
jni/curljni.c:13:28: error: 'CURLOPT_URL' undeclared (first use in this function)
jni/curljni.c:13:28: note: each undeclared identifier is reported only once for each function it appears in
/cygdrive/c/android-ndk-r8b/build/core/build-binary.mk:252: recipe for target `obj/local/armeabi/objs/curljni/curljni.o' failed
make: *** [obj/local/armeabi/objs/curljni/curljni.o] Error 1
我在Android.mk文件中尝试了很多东西,但没有成功。使用PREBUILT_SHARED_LIBRARY没有帮助,因为它只需要一个.so文件并将扩展名从.so.4.2.0更改为.so只是告诉我构建时不支持该格式...
有一件事我不确定我是否必须在我的C文件中包含标题,但是当我这样做时,它当然找不到它们。
作为一个注释,当我只使用我的Android.mk文件中声明的curl库构建(省略了C文件的共享库)时,libs文件夹中没有创建任何内容!
提前感谢您的帮助!
编辑::::
实际上它确实有效mbrenon(我已经尝试了数百万次,现在它有效,不知道有什么不同),但现在我已经
c:/android-ndk-r8b/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6.x-google/../../../. ./arm-linux-androideabi/bin/ld.exe: cannot find ./obj/local/armeabi/libcurl.a: Permission denied
我正在使用Cygwin,这可能是我遇到权限问题的原因吗? 当.so和.a被创建时,我设法绕过它,返回权限错误,chmod并再次运行ndk-build,但这看起来有点粗糙! 此外,我的卷曲功能都无法到达(“未定义参考(功能)”)。
$ ../../../ndk-build
SharedLibrary : libcurljni.so
./obj/local/armeabi/objs/curljni/curljni.o: In function `Java_test_curljni_MainActivity_stringFromJNI':
C:\android-ndk-r8b\apps\curljni\project/jni/curljni.c:12: undefined reference to `curl_easy_init'
C:\android-ndk-r8b\apps\curljni\project/jni/curljni.c:14: undefined reference to `curl_easy_setopt'
C:\android-ndk-r8b\apps\curljni\project/jni/curljni.c:15: undefined reference to `curl_easy_perform'
C:\android-ndk-r8b\apps\curljni\project/jni/curljni.c:17: undefined reference to `curl_easy_cleanup'
collect2: ld returned 1 exit status
/cygdrive/c/android-ndk-r8b/build/core/build-binary.mk:378: recipe for target `obj/local/armeabi/libcurljni.so' failed
make: *** [obj/local/armeabi/libcurljni.so] Error 1
和我的curljni.c是以下
jstring Java_test_curljni_MainActivity_stringFromJNI(JNIEnv* env, jobject thiz)
{
CURL *curl;
CURLcode res;
char buffer[10];
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "yahoo.com");
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if(res == 0)
return (*env)->NewStringUTF(env, "0 response");
else
sprintf(buffer,"code: %i",res);
return (*env)->NewStringUTF(env, buffer);
}
else {
return (*env)->NewStringUTF(env, "no curl");
}
}
我确保在curl.h中声明了所有需要的函数
答案 0 :(得分:2)
是的,您必须在C文件中包含Curl标头。要允许ndk-build在链接时查找这些头文件,您必须使用LOCAL_EXPORT_C_INCLUDES添加其路径:
include $(CLEAR_VARS)
LOCAL_MODULE:= libcurl
LOCAL_SRC_FILES := libcurl.a
LOCAL_EXPORT_C_INCLUDES := /* put the path to the Curl headers here */
include $(PREBUILT_STATIC_LIBRARY)
这将自动添加所有需要libcurl的目标中的标题的路径,并且它应该构建和链接。