2012-03-01 71 views
2

我在google android-ndk組中提出了這個問題,但沒有得到任何答案。如何在Android上使用c和java apis庫項目

我想通過點擊 來建立一個獨立項目中的通用模塊,「Is Library」是eclipse。 該項目提供了c apis和java apis。雖然其中一些 apis是相關的。 (這意味着將它們分成 兩個項目並不是一個好主意) 讓我們把它命名爲common並且libcommon.so。

當我在另一個項目(假設testcommon)使用這個庫, 我添加公共項目作爲庫在Eclipse項目在探險 - >屬性 - > Android的 - >圖書館 - >添加。 但這隻能讓我可以在庫中使用java apis。

此外,我添加libcommon.so作爲android.mk中的PREBUILT_SHARED_LIBRARYtestcommon項目,以便我可以訪問c apis。 (如下)

include $(CLEAR_VARS) 
LOCAL_MODULE := common-prebuilt 
LOCAL_SRC_FILES := ../../common/libs/$(TARGET_ARCH_ABI)/libcommon.so 
include $(PREBUILT_SHARED_LIBRARY) 

include $(CLEAR_VARS) 
LOCAL_MODULE := testCommon 
LOCAL_SRC_FILES := testCommon.c 
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../common/jni/include/ 
LOCAL_SHARED_LIBRARIES := common-prebuilt 
include $(BUILD_SHARED_LIBRARY) 

這樣,NDK,構建是成功的,但是當我運行它,我得到以下錯誤:

[2012-02-29 15:28:20 - testCommon] Error generating final archive: 
Found duplicate file for APK: lib/armeabi/libcommon.so 
Origin 1: E:\Code\EclipseWorkspace\testCommon\libs\armeabi\libcommon.so 
Origin 2: E:\Code\EclipseWorkspace\Common\libs\armeabi\libcommon.so 

我認爲這是因爲兩個參考圖書館及預生成共享 庫將libcommon.so添加到testcommon項目。其實我已經測試過只參考庫或者添加一個預構建的共享庫,他們都將libcommon.so複製到了testcommon。我讀Can shared library call another shared library?

的問題是,我該怎麼辦,如果我需要用兩個C和Java的API庫。(不僅是代碼)

感謝


後,我找到了一種方法解決這個問題但還是不太確定。

在Android.mk中使用下面的代替PREBUILT_SHARED_LIBRARY的行也會使本機部分工作,並且庫不會以這種方式複製。這樣可以修復重複的副本。

LOCAL_LDFLAGS := -L$(LOCAL_PATH)/../../Common/libs/$(TARGET_ARCH_ABI)/ -lcommon 

爲什麼不能在我之前的測試工作的原因是,即使是這樣,這兩個庫應該在基於Java的壓力,但不是唯一的libtestCommon。

System.loadLibrary("common"); // I lost this in my before test 
System.loadLibrary("testCommon"); 

我覺得現在很清楚我。

LOCAL_SHARED_LIBRARIES和-L plus -l都應該在NDK中正常工作。

的問題是,當我叫

System.loadLibrary("testCommon") 

它會嘗試找到/數據/數據/ $(應用程序路徑)/ lib目錄(System.java::loadLibrary所以文件 - >運行。 java :: loadLibrary - > DexPathList.java::findLibrary)但是當libtestCommon試圖找到它的依賴libCommon。所以,它只會在/供應商/ lib和/系統/ lib中找到它,因爲

LD_LIBRARY_PATH=/vendor/lib:/system/lib. 

如果我打電話的System.loadLibrary( 「通用」)第一,dlopen的將其加載到高速緩存(Linker.c :: alloc_info)。這使得libtestCommon.so加載libCommon.so我猜成功了。所以一切正常。

我還注意到這些詞語在SYSTEM-ISSUES.html在NDK-R7結束:

  • 一個錯誤防止一個應用程序共享庫從根據另一個 之一。例如,如果爲您的 應用程序構建libfoo.so和libbar.so,並將libfoo.so作爲libbar.so的依賴項列入 bar/Android.mk(使用LOCAL_SHARED_LIBRARIES:= foo),然後加載 libbar .so將始終失敗,即使您已經在您的進程中加載​​了libfoo.so 。

有一點不同。如果我已經在我的進程中加載​​了libfoo.so,libbar.so會成功。

所以,答案在最後的是:

  • 使用LOCAL_LDFLAGS:= -Lxx -lxx如果您需要在Android的庫項目中的任何共享庫。
  • 您必須爲每個需要的共享庫調用System.loadLibrary。這也是在一個庫中使用另一個共享庫的方法。
  • /libs /中庫的路徑位於/ data/data // lib /。

回答

0

作爲一個選項,您可以使用

LOCAL_ALLOW_UNDEFINED_SYMBOLS:=真

在Android.mk之一,排除重複的庫。

0

我一直在摔跤類似的問題。我想用Java和C構建一個Android庫項目。我希望依賴項目的Java能夠在JNI中引用庫的Java和依賴項目的C代碼,以便能夠引用庫的jni中的C.我需要兩件咒語。其中一個與您的解決方案几乎完全相同:

LOCAL_LDFLAGS := -L$(LOCAL_PATH)/../../Common/libs/$(TARGET_ARCH_ABI)/ -lcommon 

我創建了對文件系統中庫項目實際位置的依賴關係。您的依賴關係假設常見庫項目是您的從屬項目TestCommon項目的同級目錄。

我還創建了一個build.xml Ant文件,它將庫項目中的C頭文件複製到相關jni文件夾中的jni/include目錄中。

有了這兩個kludges,我能夠得到一切工作。我真的想要消除這兩個問題,但是找不到方法。