问题描述
我已经要求在谷歌的Android NDK组这个问题,但没有得到任何答复。
我想通过点击一个独立的项目,建立一个通用模块在是图书馆,是日食。该项目提供了使用C的API和Java API。虽然其中一些API是相关的。 (这意味着这不是一个好主意,将它们分开到2个项目)让我们将其命名为常见,libcommon.so。
当我使用这个库中的其他项目(假设testcommon)我想补充的公共项目作为库在Eclipse中的项目资源管理器 - >属性 - > Android的 - >库 - >添加。但是,这只是让我可以使用的Java API库。
另外我想补充libcommon.so为preBUILT_SHARED_LIBRARY在android.mk在testcommon项目,这样我可以访问Ç的API。 (如下)
包括$(CLEAR_VARS)
LOCAL_MODULE:=共prebuilt
LOCAL_SRC_FILES:= ../../common/libs/$(TARGET_ARCH_ABI)/libcommon.so
包括$(preBUILT_SHARED_LIBRARY)
包括$(CLEAR_VARS)
LOCAL_MODULE:= testCommon
LOCAL_SRC_FILES:= testCommon.c
LOCAL_C_INCLUDES:= $(LOCAL_PATH)/../../通用/ JNI /有/
LOCAL_SHARED_LIBRARIES:=共prebuilt
包括$(BUILD_SHARED_LIBRARY)
在这种方式,NDK建造是成功的,但是当我运行它,我得到以下错误:
[2012-02-29 15点28分二十秒 - testCommon]错误产生最终的归档文件:
为APK找到重复的文件:LIB / armeabi / libcommon.so
原产地1:E:\ code \ EclipseWorkspace \ testCommon \库\ armeabi \ libcommon.so
原产地2:E:\ code \ EclipseWorkspace \公用\库\ armeabi \ libcommon.so
我觉得,因为这两个参考图书馆和prebuild共享库libcommon.so添加到testcommon项目。事实上,我已经测试只引用该库或添加prebuild共享库,它们都复制libcommon.so到testcommon。
现在的问题是,我该怎么办,如果我需要使用C和Java API库。(不仅是code)
感谢
在我读能共享库调用另一个共享库? ,我找到了一种方法来解决这个问题,但仍然没有十分的把握。
使用以下线Android.mk代替preBUILT_SHARED_LIBRARY也使当地部分工程和库不会以这种方式被复制。让副本可以是固定的。
LOCAL_LDFLAGS:= -L $(LOCAL_PATH)/../../通用/库/ $(TARGET_ARCH_ABI)/ -lcommon
为什么不能在我之前的测试工作的原因是,即使是这样,无论是图书馆应该是负载在Java中,但不是唯一libtestCommon。
的System.loadLibrary(通用); //我在之前的测试失去了这种
的System.loadLibrary(testCommon);
我想很明显对我来说吧。
无论LOCAL_SHARED_LIBRARIES和-L加上-l应该很好地工作在NDK。
现在的问题是,当我称之为
的System.loadLibrary(testCommon)
它会试图找到这样的文件在/数据/数据/ $(应用程序路径)/ lib目录(System.java::loadLibrary - > Runtime.java::loadLibrary - > DexPathList.java::findLibrary),但当libtestCommon试图找到它的依赖libCommon.so,它只会发现它在自
/供应商/ lib和/系统/ lib目录 LD_LIBRARY_PATH = /供应商/ lib目录下:/系统/ lib目录下。
如果我称之为的System.loadLibrary(通用)第一,将的dlopen加载到缓存中(Linker.c :: alloc_info)。这使得libtestCommon.so负载libCommon.so成功,我猜。所以,一切正常。
我也NDK-R7注意到这句话在SYSTEM-ISSUES.html年底
有一点点不同。如果我已经加载了libfoo.so在我的过程中,libbar.so会成功。
所以,最后的答案是:
- 使用LOCAL_LDFLAGS:= -Lxx -lxx,如果你需要的Android库项目的任何共享库。
- 您必须调用的System.loadLibrary为每一个需要的共享库。这也是使用另一个共享库在一个图书馆该怎么走。
- 在图书馆的/库/置于/数据/数据// lib目录/. 的路径
我一直在摔跤了类似的问题。我想用Java和C.建立一个Android库的项目,我想取决于项目的Java成为能够引用该库的Java和相关的项目C code在JNI来能够引用C库的JNI 。我需要两个组装机。一个几乎是相同的解决方案:
LOCAL_LDFLAGS:= -L $(LOCAL_PATH)/../../通用/库/ $(TARGET_ARCH_ABI)/ -lcommon
我创建文件系统库项目的实际位置的依赖。你的依赖假设的通用的库项目是同级目录中相关的 TestCommon 的项目。
我还创建了一个build.xml Ant文件的副本,从库项目的C头文件到JNI / include目录中的相关JNI文件夹。
通过这两个组装机,我能得到的一切工作。我真的想消除这两个组装机,但找不到办法。
I have asked this question in google android-ndk group but not get any answer.
I am trying to build a common module in a independent project by click the "Is Library" is eclipse. This project provides both c apis and java apis. While some of these apis are related. ( it means it's not a good idea to separate them into 2 projects) Let's name it common and libcommon.so.
When I am using this library in another project ( suppose testcommon), I add the common project as a library in eclipse at project explorer--> properties --> Android --> Library --> Add. But this only make me possible to use java apis in the library.
Also I add libcommon.so as a PREBUILT_SHARED_LIBRARY in android.mk in testcommon project so that I could access c apis. ( as below )
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)
In this way, ndk-build is success but when I am running it, I get below errors:
[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
I think that because both reference to library and prebuild shared library add libcommon.so to testcommon project. In fact, I have tested to only reference the library or add a prebuild shared library, they both copied libcommon.so to testcommon.
The question is, what should I do if I need a library with both c and java apis.( not only code )
Thanks
After I read Can shared library call another shared library?, I found a way to solve this but still not very sure.
Use below line in Android.mk instead of PREBUILT_SHARED_LIBRARY also make native part works and libraries will not be copied in this way. So that duplicate copy could be fixed.
LOCAL_LDFLAGS := -L$(LOCAL_PATH)/../../Common/libs/$(TARGET_ARCH_ABI)/ -lcommon
The reason why this could not work in my before test is that even is this way, both libraries should be load in java, but not only libtestCommon.
System.loadLibrary("common"); // I lost this in my before test
System.loadLibrary("testCommon");
I think it's clear for me now.
Both LOCAL_SHARED_LIBRARIES and -L plus -l should work fine in NDK.
The problem is that when I call
System.loadLibrary("testCommon")
it will try to find so files at /data/data/$(app path)/lib (System.java::loadLibrary --> Runtime.java::loadLibrary --> DexPathList.java::findLibrary ) but when libtestCommon try to find its dependency libCommon.so, it will only find it at /vendor/lib and /system/lib since
LD_LIBRARY_PATH=/vendor/lib:/system/lib.
If I call System.loadLibrary("common") first, dlopen will load it into cache (Linker.c::alloc_info). This make libtestCommon.so loads libCommon.so success I guess. So everything works.
I also noticed these words at the end of SYSTEM-ISSUES.html in ndk-r7:
There is a little different. If I have already loaded libfoo.so in my process, libbar.so will success.
So, answer at last is:
- Use LOCAL_LDFLAGS := -Lxx -lxx if you need any shared libraries in android library project.
- You must call System.loadLibrary for every shared libraries needed. That's also the way to use another shared library in one library.
- The path of libraries at /libs/ is placed at /data/data//lib/.
I have been wrestling with a similar problem. I want to build an Android library project with both Java and C. I want dependent projects' Java to be able to reference the library's Java and dependent projects' C code in JNI to be able to reference the C in the library's jni. I required two kludges. One is almost identical to your solution:
LOCAL_LDFLAGS := -L$(LOCAL_PATH)/../../Common/libs/$(TARGET_ARCH_ABI)/ -lcommon
I created a dependency on the library project's actual location in the file system. Your dependency assumes the Common library project is a sibling directory of your dependent TestCommon project.
I also created a build.xml Ant file that copies the C header files from the library project to a jni/include directory in the dependent jni folder.
With these two kludges, I am able to get everything working. I would really like to eliminate both kludges, but could not find a way.
这篇关于如何使用库项目在Android上使用C和Java API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!