arm共享库的重用
Reuse of arm shared library
我已经建立了arm android共享库(libtest.so)。我对重用一个函数感兴趣(它没有很多依赖关系——它只是创建类实例并调用两个方法)。我想调用该函数(它接受一个std::string参数)并获得返回值。
有可能这样做吗?我没有任何头文件。
我试过这个Android。mk,我放libtest。在/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样本中添加预构建库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
的设备上)。可能出了什么问题?
我有一个应用程序,我做的事情与您需要的类似(或者可能正是您需要的)。
-
我已经以*的形式预编译了库。所以文件。(如lib1。所以,lib2。所以等),
-
我已经创建了一个模块,它通过包括它们的头和*来使用预编译的库。所以文件。在这个例子中,我称之为"libtestwrapper"。模块定义自己的源文件,并可选地包含。模块功能可以导出到第二个模块(如果你提供头文件),后面会解释。
-
我创建了第二个模块(newModule),它通过将其添加到'LOCAL_SHARED_LIBRARIES'来使用第一个模块(libtestwrapper)。这使得你之前导出的头文件(在'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 (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)
如果库不是用Android构建工具(即NDK)构建的,那么它可能不会有兼容的ABI。即使它是使用gcc的ARMv5 EABI兼容版本构建的,如果它依赖于任何libc/libc++,那么它将失败。仿生C库与其他C/c++库不二进制兼容,您必须针对它构建本机代码,即使是共享库。
如果你想从Java调用一个c++方法,并且需要传递像字符串这样的类型,你应该使用JNI (Java Native接口)编写一个转换层。
你可以在网上找到一些关于如何做到这一点的教程。一个例子
作为总结
1-在Java中声明一个本机方法
2-生成应该从c++库中导出的签名,该签名将在Java中调用此方法时被调用。
示例命令:javah com.companyname.JavaTestCaller
该命令将生成一个带有相应签名的头文件。
3-准备一个包含此方法的c++库。在这个方法中做任何您想做的事情(调用libtest。如果你想的话)并返回结果。当需要进行类型转换时,使用from方法。
4-把这个新库放在libtest旁边。在你的应用中。在libtest.so之后加载这个库。
你试过改变这一行吗?
LOCAL_SHARED_LIBRARIES := libtest
:
LOCAL_SHARED_LIBRARIES := test
lib和.so将自动用于解析共享库名称。您还应该能够使用:
LOCAL_LDLIBS += -ltest
PREBUILT_SHARED_LIBRARY是另一个选项。
由于没有头文件,因此可能需要编写一个共享库,用于调用预构建库。您的应用程序将调用新的共享库,它将导出正确的JNI符号名称,新的共享库将调用md5()函数。
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 在cuda线程之间共享大量常量数据
- 如何从具有移动语义的类对象中生成共享指针
- 在c代码之间共享数据的最佳方式
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 将静态库链接到不带-fPIC的共享库中
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 为什么std::互斥需要很长的、非常不规则的时间来共享
- 使用Boost Interprocess创建托管共享内存需要很长时间
- 无法在Ubuntu上将共享库与Eclipse链接
- 从python调用openMP共享库时,未定义opnMP函数
- 在为LINUX创建共享库时,如何避免STL的私有/弱副本
- 为什么我的共享库中存在展开符号
- 使用共享指针的函数调用,其对象应为 const
- 具有两个独占锁组的共享锁
- 共享队列的线程安全
- 共享指针和具有自定义删除程序的唯一指针之间的语法差异背后的任何原因
- 在arm Debian上加载共享库时出错
- arm共享库的重用