重用arm共享库

时间:2014-03-16 18:32:32

标签: android c++ shared-libraries

我已经构建了arm arm共享库(libtest.so)。我有兴趣重用一个函数(没有很多依赖项 - 它只创建类实例并调用两个方法)。我想调用该函数(它需要一个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示例中添加prebuild库:

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上的设备上)。可能有什么问题?

4 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

如果要从Java调用C ++方法并且需要传递类似string的类型,则应使用JNI(Java Native interface)编写转换层。

您可以在互联网上找到有关如何完成此操作的几个教程。一个例子 here

作为摘要

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

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

示例命令:javah com.companyname.JavaTestCaller

此命令将生成带有相应签名的头文件。

3-准备包含此方法的c ++库。在此方法中执行任何操作(如果需要,请调用libtest.so)并返回结果。使用类型转换时的方法。

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

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

答案 2 :(得分:0)

您是否尝试更改此行:

LOCAL_SHARED_LIBRARIES := libtest

为:

LOCAL_SHARED_LIBRARIES := test

lib和.so会自动用于解析共享库名称。您还应该能够使用:

LOCAL_LDLIBS += -ltest

PREBUILT_SHARED_LIBRARY是另一种选择。

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

答案 3 :(得分:0)

我有一个应用程序,我会做一些类似于你需要的东西(或者你可能正是你需要的东西)。

  1. 我有* .so文件形式的预编译库。 (例如lib1.so,lib2.so等), 带有一些标题。

  2. 我创建了一个模块,它通过包含头文件和* .so文件来利用预编译库。在示例中,我将其称为“libtestwrapper”。该模块定义了自己的源文件,并可选择包含。可以为第二个模块导出模块功能(如果提供头文件),如后面所述。

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

  4. 以下是我的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 (i.e. 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)