如何使用库项目在Android上使用C和Java API [英] How to use a library project with both c and java apis on Android

查看:189
本文介绍了如何使用库项目在Android上使用C和Java API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经要求在谷歌的Andr​​oid 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年底

  
      
  • 中的错误prevents一个应用程序分享了这取决于其他图书馆   一。例如,如果你建立两个libfoo.so和libbar.so您   应用程序,并列出libfoo.so作为libbar.so的依赖   酒吧/ Android.mk(带LOCAL_SHARED_LIBRARIES:= FOO),然后装载   libbar.so总是会失败,即使你已经加载libfoo.so   在你的进程。
  •   

有一点点不同。如果我已经加载了libfoo.so在我的过程中,libbar.so会成功。

所以,最后的答案是:

  • 使用LOCAL_LDFLAGS:= -Lxx -lxx,如果你需要的Andr​​oid库项目的任何共享库。
  • 您必须调用的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:

  • A bug prevents one application shared library from depending on another one. For example, if you build both libfoo.so and libbar.so for your application, and list libfoo.so as a dependency for libbar.so in bar/Android.mk (with LOCAL_SHARED_LIBRARIES := foo), then loading libbar.so will always fail, even if you have already loaded libfoo.so in your process.

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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆