重新使用arm共享库

我已经build立了ARM的android共享库(libtest.so)。 我有兴趣重复使用一个函数(这不是很多依赖关系 – 它只是创build类实例并调用两个方法)。 我想调用该函数(它需要一个std :: string参数)并获取返回的值。

有没有可能做这样的事情? 我没有任何头文件。

我试过这个Android.mk,我把libtest.so放在/jni/libs/armeabi/lib/armeabi 。 在这一点上,我的cpp文件编译,但现在呢? 如果可能的话,我如何从libtest.so调用函数? 我知道它从objdump的名字

  LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE:= libtest LOCAL_SRC_FILES := libtest.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := hello-jni LOCAL_SRC_FILES := hello-jni.cpp LOCAL_SHARED_LIBRARIES := libtest include $(BUILD_SHARED_LIBRARY) 

编辑:

我试图从这个android.mk添加hello-jni示例的预build库:

 include $(CLEAR_VARS) LOCAL_MODULE:= libhello-jni LOCAL_SRC_FILES := libhello-jni.so include $(PREBUILT_SHARED_LIBRARY) 

它的工作,但libtest.so相同的代码显示以下错误(开始时)

 UnsatisfiedLinkError: Cannot load libtest.so: FindLibrary returned null 

libtest.so位于libhello-jni.so旁边的文件夹(在/data/data/[package]/lib )。 什么可能是错的?

Solutions Collecting From Web of "重新使用arm共享库"

我有一个应用程序,在那里我做类似于你需要的东西(或者正是你所需要的)。

  1. 我有* .so文件的forms预编译库。 (例如lib1.so,lib2.so等),它们附带一些头文件。

  2. 我已经创build了一个使用预编译库的模块,包括它们的头文件和* .so文件。 在这个例子中,我称之为“libtestwrapper”。 该模块定义自己的源文件,并可以select包含。 如稍后所述,可以将模块function导出为第二个模块(如果您提供了头文件)。

  3. 我创build了第二个模块(newModule),它将第一个模块(libtestwrapper)添加到“LOCAL_SHARED_LIBRARIES”中。 这使得以前导出的头文件(在'libtestwrapper'中)可用于'newModule'。

这里是我的Android.mk的内容:

 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libtestwrapper LOCAL_SRC_FILES := libtestUsage.c # Use the methods of libtest.h here LOCAL_C_INCLUDES := $(LOCAL_PATH)/include # This is where libtest.h should be # provide this line if you intend to export any header files to another module #LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/include # you may also use a different directory than 'include' LOCAL_LDLIBS := -L$(LOCAL_PATH)/dir_with_libtest_so -libtest # -llog etc. #optionally add any as needed: -llog -ljnigraphics -lz -ldl -lgcc # '-libtest' corresponds to 'libtest.so' - the names must match # -llog is for logcat for example include $(BUILD_SHARED_LIBRARY) # Optional: # Define a second module wich is making use of the first one (ie libtestwrapper) include $(CLEAR_VARS) LOCAL_MODULE := newModule # this module will be making use of the first one (if needed) # Add local source files. If the files are stored in directories # you have to provide a relative path starting inside the 'jni' directory. # The example is for this structure: jni/dirToSourceFiles1/*.cpp LOCAL_SRC_FILES := dirToSourceFiles1/SourceFile1.cpp dirToSourceFiles1/SourceFile2.cpp LOCAL_C_INCLUDES += $(LOCAL_PATH)/newModule_include # path where the headers of this module are stored LOCAL_SHARED_LIBRARIES += libtestwrapper # make use of the previous module # Optionally add this line if any other libs should be used #LOCAL_LDLIBS := -llog -ljnigraphics -lz -ldl -lgcc include $(BUILD_SHARED_LIBRARY) 

如果库不是用Android构build工具(即NDK)构build的,那么它可能没有兼容的ABI。 即使它是用一个ARMv5 EABI兼容版本的gcc构build的,如果它依赖于任何libc / libc ++,那么它将会失败。 仿生C库与其他C / C ++库不是二进制兼容的,您必须针对它build立本机代码,即使是共享库也是如此。

如果您想从Java调用C ++方法,并且需要传递stringtypes,则应使用JNI(Java Native接口)编写转换层。

你可能会find几个关于如何在互联网上完成的教程。 这里是一个例子

作为总结

1-在Java中声明一个本地方法

2-生成应从您的c ++库中导出的签名,在Java中调用此方法时将调用该签名。

示例命令:javah com.companyname.JavaTestCaller

这个命令将生成一个带有适当签名的头文件。

3-准备一个包含这个方法的c ++库。 在这个方法中做任何你想要的(如果你想要的话,调用libtest.so)并返回结果。 使用从types转换是必要的方法。

4-将这个新的库放在你的应用程序的libtest.so旁边。 在libtest.so之后加载这个库。

5-从您的应用程序调用本地Java方法。

你有没有试过改变这一行:

 LOCAL_SHARED_LIBRARIES := libtest 

至:

 LOCAL_SHARED_LIBRARIES := test 

lib和.so会自动用于parsing共享库名称。 你应该也可以使用:

 LOCAL_LDLIBS += -ltest 

PREBUILT_SHARED_LIBRARY是另一种select。

由于您没有头文件,因此您可能需要编写一个用于调用预build库的共享库。 你的应用程序将调用新的共享库,它导出正确的名称JNI符号,新的共享库将调用md5()函数。