的Android NDK:比预编译库中指定
我生成C++库使用Android SDK编译器使用手动静态库是不同的。结果是libMyUtils.a。的Android NDK:比预编译库中指定
我用我的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。很显然,我所调用的本地函数不在库中。我究竟做错了什么?
在端部的解决方案是构建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)
通知的。所以的推广与该PREBUILT_ SHARED _LIBRARY和BUILD_ SHARED _LIBRARY脚本。
一个完整的解释,因为你的Android.mk对我没有多大意义:对不起,如果你已经知道一些。
静态库应该是纯C/C++,并且使用Android NDK进行封装以便可以从Java使用。
highfive.h:
int giveMeFive();
highfive.c:
#include "highfive.h"
int giveMeFive() {
return 5;
}
例如,假设您的静态库是由一个简单的.c和.h文件建
这可以被编译为使用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)
还有,你应该能够为你想使用你的本地库!
希望这有助于!
通常,静态库包含许多对象,其中包含许多功能,其中许多是未使用的。这就是为什么链接器只从静态库中提取引用的对象。所以,在由@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)
我已经试过这个解决方案。我不知道为什么,但似乎没有工作。这很有道理。在这之后,我的图书馆仍然是空的。但我找到了解决方案。 – Emmanuel
你是怎么建立'../../../../ libs/libMyUtils.so'的? –
我使用cmake以及http://code.google.com/p/android-cmake/,所以我将cmake脚本更改为使用SHARED而不是STATIC。 – Emmanuel
是的,这是最简单的修复方法。 –