2012-06-03 108 views
6

我用成功將編譯庫LibXtract編譯爲共享庫libxtract.so並且想用在第二個工程中。Android下的鏈接共享庫NDK

在提到項目中,我嘗試編譯它簡單的功能:

#include <com_androidnative1_NativeClass.h> 
#include <android/log.h> 
#include "libxtract.h" 

JNIEXPORT void JNICALL Java_com_androidnative1_NativeClass_showText 
(JNIEnv *env, jclass clazz) 
{ 

    float mean = 0, vector[] = {.1, .2, .3, .4, -.5, -.4, -.3, -.2, -.1}, spectrum[10]; 
    int n, N = 9; 
    float argf[4]; 

    argf[0] = 8000.f; 
    argf[1] = XTRACT_MAGNITUDE_SPECTRUM; 
    argf[2] = 0.f; 
    argf[3] = 0.f; 

    xtract[XTRACT_MEAN]((void *)&vector, N, 0, (void *)&mean); 
    __android_log_print(ANDROID_LOG_DEBUG, "LIbXtract", "Button pushe2"); 
} 

我有扁平的結構:

  • JNI/com_androidnative1_NativeClass.c
  • JNI/com_androidnative1_NativeClass.hjni/libxtract。 h
  • jni/other * .h文件來自libxtract界面
  • jni/A ndroid.mk
  • JNI/Applicatoin.mk

庫libxtract.so我把mainproject/lib文件夾

我Android.mk文件看起來像:

LOCAL_PATH := $(call my-dir) 
include $(CLEAR_VARS) 
LOCAL_SRC_FILES := com_androidnative1_NativeClass.c 
LOCAL_MODULE := com_androidnative1_NativeClass 
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ 
LOCAL_LDLIBS += -llog 
LOCAL_SHARE_LIBRARIES := libxtract 
NDK_MODULE_PATH += $(LOCAL_PATH)/../lib/ 
include $(BUILD_SHARED_LIBRARY) 

,我仍然出現錯誤:

Compile thumb : com_androidnative1_NativeClass <= com_androidnative1_NativeClass.c 
SharedLibrary : libcom_androidnative1_NativeClass.so./obj/local/armeabi/objs/com_androidnative1_NativeClass/com_androidnative1_Nativ eClass.o: In function `Java_com_androidnative1_NativeClass_showText': 
/home/jack/Projects/AndroidNative1/jni/com_androidnative1_NativeClass.c:20: undefined reference to `xtract' 
collect2: ld returned 1 exit status 
make: *** [obj/local/armeabi/libcom_androidnative1_NativeClass.so] Error 1 

代碼來自LibXtract的示例和C++ com沒有問題的堆,任何想法?

+0

您具體是如何編譯libxtract.so?你爲什麼不把它的編譯添加到同一個Android.mk文件中,這樣兩個共享庫可以同時創建? –

+1

我通過採用這種解決方案編譯它[鏈接](http://stackoverflow.com/a/7308682/1409501)我只是添加碎紙庫,以保持它簡單 – Jack

+1

這個答案聽起來像解決您的問題。 http://stackoverflow.com/questions/10593987/android-ndk-linking/10615769#10615769 – codetiger

回答

4

您的Android make文件應該是...

LOCAL_PATH := $(call my-dir) 

include $(CLEAR_VARS) 

LIB_PATH := $(LOCAL_PATH)/../lib 
LOCAL_SRC_FILES := com_androidnative1_NativeClass.c 
LOCAL_MODULE := com_androidnative1_NativeClass 
LOCAL_LDLIBS += -llog 

LOCAL_LDLIBS + = $(LIB_PATH)-lxtract

LOCAL_SHARE_LIBRARIES := libxtract 
include $(BUILD_SHARED_LIBRARY) 

嘗試在你的第二個項目這個make文件,並您可以成功構建代碼而不會出現任何錯誤。

+0

我使用你的和@FooF解決方案,我的Android.mk看起來像: LOCAL_PATH:= $ (叫我-DIR) 包括$(CLEAR_VARS) LOCAL_MODULE:= libxtract LOCAL_SRC_FILES:= libxtract.so 包括$(PREBUILT_SHARED_LIBRARY) 包括$(CLEAR_VARS) LIB_PATH:= $(LOCAL_PATH)/../ lib/libxtract.so 個LOCAL_SRC_FILES:= com_androidnative1_NativeClass.c LOCAL_MODULE:= com_androidnative1_NativeClass LOCAL_LDLIBS + = -llog LOCAL_LDLIBS + = $(LIB_PATH) LOCAL_SHARE_LIBRARIES:= libxtract 包括$(BUILD_SHARED_LIBRARY) – Jack

+0

及其構建成功,但是當我運行的代碼,其中我使用它我得到錯誤: 06-04 21:58:26.504:E/AndroidRuntime(14792):引起:java.lang.UnsatisfiedLinkError:無法加載libxtract:findLibrary返回null當然我使用System.loadLibrary( 「libxtract」); – Jack

+0

看看,在成功構建libxtract.so之後,在第二個項目中使用此make文件。並且LIB_PATH應該是正確的。在你的第二個項目make文件中應該使用'LOCAL_LDLIBS + = $(LIB_PATH)-lxtract',否則你會得到你在上面發佈的錯誤。 –

2

你需要告訴Android NDK構建腳本關於你的共享庫。請查詢${NDK}/doc/PREBUILTS.html瞭解如何完成此操作。他們建議增加Android.mk在同一目錄下,你有你的libXtract.so

LOCAL_PATH := $(call my-dir) 
include $(CLEAR_VARS) 
LOCAL_MODULE := libXtract 
LOCAL_SRC_FILES := libXtract.so 
include $(PREBUILT_SHARED_LIBRARY) 

調試提示:我猜你正在使用ndk-build打造你的「第二個項目」。嘗試運行ndk-buildV=99(嘗試V=99 ndk-buildndk-build V=99 - 我的記憶失敗)。這會向您顯示確切的失敗鏈接命令。您應該可能有選項-lXtract-L/path/to/libXtract/library。 (有時可以很方便地複製並粘貼鏈接命令來手動運行它來尋找成功連接了正確的選項,其實固定構建設置之前。)

更新:我現在看到@ codetiger的評論似乎指向同樣的答案(沒有提到NDK文件是很好的閱讀 - 所以我不刪除這個答案)。

2

在上面的答案都是正確的,但免除一個。

當我們想鏈接lib時,我們必須add -L之前LOCAL_LDLIBS dir如下所示。

LIB_PATH := $(LOCAL_PATH)/../lib 

LOCAL_LDLIBS += **-L**$(LIB_PATH) -lxtract 

否則它會給如下錯誤

cannot open XXX/../lib: Permission denied

+1

你能澄清你所引用的答案嗎? –

+0

在搜索路徑中包含共享庫的語法。 1)必須通過-L指令指定路徑,然後2)之後立即通過-l指令共享庫。 – drlolly