我使用Android SDK编译器手动构建C ++库。结果是libMyUtils.a。
我在Java / JNI测试应用程序中使用以下内容:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyUtils
LOCAL_SRC_FILES := ../../../../libs/libMyUtils.a
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_MODULE := AndroidTests
LOCAL_STATIC_LIBRARIES := MyUtils
include $(BUILD_SHARED_LIBRARY)
构建控制台时显示以下内容:
[armeabi] Install : libMyUtils.so => libs/armeabi/libMyUtils.so
现在由于一些奇怪的原因,库../../../../libs/libMyUtils.a是几兆字节,但库libs / armeabi / libMyUtils.so只有5KB。它不应该是同一个图书馆吗?
当我运行我的测试应用程序时,我得到UnsatisfiedLinkError。显然我正在调用的本机函数不在库中。我做错了什么?
答案 0 :(得分:0)
一个完整的解释,因为你的Android.mk对我来说没有多大意义:对不起,如果你已经知道了一些。
静态库应该是纯C / C ++,并使用Android NDK包装,以便可以从Java中使用。
例如,假设您的静态库是使用简单的.c和.h文件构建的:
highfive.h:
int giveMeFive();
highfive.c:
#include "highfive.h"
int giveMeFive() {
return 5;
}
这可以使用Android NDK编译器编译为静态库,显然您已经知道如何操作:这将为我们提供highfive.a
库。
在这种形式中,此库不能从Java中使用,但可以使用Android NDK进行包装。有关命名约定等,请参阅Android NDK文档...
highfiveWrapper.c:
#include "highfive.h"
jint
Java_your_package_name_HighFive_giveMeFive(JNIEnv *env, jobject o) {
return (jint) giveMeFive();
}
及其相应的Java文件:
package your.package.name;
class HighFive {
static {
System.loadLibrary("highfive");
}
public native int giveMeFive();
}
现在,我们如何编译所有这些以使其工作:
Android.mk:
include $(CLEAR_VARS)
LOCAL_MODULE := libhighfive-prebuilt
LOCAL_SRC_FILES := path/to/highfive.a
LOCAL_EXPORT_C_INCLUDES := path/to/highfive.h/folder
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := highfive
LOCAL_SRC_FILES := path/to/highfiveWrapper.c
LOCAL_STATIC_LIBRARIES := libhighfive-prebuilt
include $(BUILD_SHARED_LIBRARY)
在那里你应该能够按照自己的意愿使用你的本地图书馆!
希望这有帮助!
答案 1 :(得分:0)
通常,静态库包含许多对象,这些对象包含许多未使用的函数。这就是链接器仅从静态库中提取引用对象的原因。因此,在@mbrenon给出的示例中,highfiveWrapper.c
定义highfive.a
的哪些组件将链接到highfive.so
。
但是在您的设置中,您需要加载整个静态库。好的,有一个特殊的词:LOCAL_WHOLE_STATIC_LIBRARIES。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyUtils
LOCAL_SRC_FILES := ../../../../libs/libMyUtils.a
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_MODULE := AndroidTests
LOCAL_WHOLE_STATIC_LIBRARIES := MyUtils
include $(BUILD_SHARED_LIBRARY)
答案 2 :(得分:0)
最后,解决方案是将MyUtils库构建为预建的共享库。这样链接器就不会剥离任何东西。然后我按如下方式修改了我的makefile:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyUtils
LOCAL_SRC_FILES := ../../../../libs/libMyUtils.so
include $(PREBUILT_SHARED_LIBRARY)
LOCAL_MODULE := AndroidTests
LOCAL_SHARED_LIBRARIES := MyUtils
include $(BUILD_SHARED_LIBRARY)
请注意 .so 扩展和PREBUILT_ SHARED _LIBRARY和BUILD_ SHARED _LIBRARY脚本。