2012-11-13 72 views
4

我遇到了使用Android NDK r8b鏈接Android項目中的C庫的問題。 我使用ARM的工具鏈構建了cURL庫(沒有SSL),它爲我提供了一個libcurl.a文件和一個libcurl.so.4.2.0文件。 我也創建了一個C文件來爲我的Java代碼提供函數並使用cURL庫。鏈接.a已編譯的庫和自己的共享庫Android NDK r8b

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 

我m使用Cygwin,這可能是我遇到權限問題的原因嗎? 當.so和.a被創建時,我設法解決它,返回許可錯誤,chmod並再次運行ndk-build,但是這看起來有點粗糙! 加上現在我的curl函數都不可以達到(「undefined reference to(function)」)。

$ ../../../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

你可以給我一個方法來建立在Windows系統libcurl.a我有下載curl 7.29。 – Herry

回答

2

是的,你必須包括捲曲頭中你的C文件。爲了讓NDK建造找到在鏈接時這些頭文件,你必須添加通過其路徑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,它應該建立和聯繫。

+0

我不幸地嘗試過,但已經沒有成功,添加行 LOCAL_EXPORT_C_INCLUDES:= $(LOCAL_PATH)/ include/curl 但ndk-build工具報告我 jni/curljni.c:5:18:致命錯誤:curl.h :沒有這樣的文件或目錄 – PeterGriffin

+0

顯然你需要在libcurl.a上設置完整的權限。在Cygwin輸入'chmod -R 777/*路徑到你的「obj」文件夾* /'應該可以做到! – mbrenon

+0

是的,必須建立它並chmod它,然後重建。我現在有一個「未定義的引用(函數)」,用於我在.c文件中使用的所有Curl函數! – PeterGriffin