Android NDK:使用的静态库与指定的预编译库不同
Android NDK: Static library used is different than precompiled library specified
我使用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/libMyUtil.so只有5KB。它不应该是同一个图书馆吗?
当我运行我的测试应用程序时,我会得到不满意的链接错误。很明显,我调用的本机函数不在库中。我做错了什么?
一个完整的解释,因为你的Android.mk对我来说没有多大意义:对不起,如果你已经知道其中的一些。
静态库应该是纯C/C++,并使用AndroidNDK进行封装,以便从Java中使用。
例如,假设您的静态库是从一个简单的.c和.h文件构建的:
高音。h:
int giveMeFive();
高音。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)
在那里,你应该可以随心所欲地使用你的本地图书馆!
希望这能有所帮助!
通常,静态库包含许多对象,这些对象包含许多函数,其中许多函数是未使用的。这就是为什么链接器只从静态库中提取引用的对象。因此,在@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)
最终,解决方案是将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_SHAREDLIBRARY脚本。
- Android NDK 编译 LAME HAVE_MPGLIB > 'interface.h' 文件未找到
- 为 Android NDK 编译库
- 将预编译的 C 共享库与 JNI/NDK 结合使用
- 使用 Android NDK 使用 clang++ 编译C++代码时对"_Unwind_Resume"的未定义引用
- "ndk-build finish with non-zero exit value 2" 在编译文本仙女项目时
- 在 NDK 上编译两个带有 gradle 的项目,其中一个依赖于另一个的二进制文件
- 编译 android .so 库在 Visual Studio 错误与 android ndk 15c __signbi
- C/C 代码与不同NDK编译的C/C 代码的兼容性
- 使用WEBRTC编译NDK项目
- 交叉编译时 NDK 工具链中的 /system/bin/linker 在哪里
- 为什么我们需要使用android工具链(或NDK)来编译在android应用程序上下文中运行的c/c++代码
- 如何编译安卓 ndk 活页夹源代码
- Android ndk: utils/Log.h: 没有这样的文件或目录编译终止
- 如何在eclipse Android(NDK)中编译C/C++代码
- 使用与Application.mk中定义的STL不同的STL编译android ndk模块
- Android NDK:使用的静态库与指定的预编译库不同
- 使用 Android NDK 编译原生C++共享对象
- 使用 ndk clang 3.4/3.5 编译__thread没有运气
- 如何使用 Android NDK 编译带有成员函数的结构
- 使用RefBase或IBinder时,__Atomic导致NDK编译错误