我正在编写一个Android应用程序,希望将JNI调用成为使用NDK构建的共享库.诀窍是这个共享库调用OTHER共享库提供的函数.其他共享库是已在其他地方编译的C库.
这是我尝试过的:
我的环境: 我在Eclipse工作.我添加了原生支持并拥有一个jni库.在那个库中,我有我的代码和\ lib目录,我已经复制了我的其他.so文件.
尝试#1 Android.mk:告诉它libs在哪里
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := native_lib
LOCAL_SRC_FILES := native_lib.cpp
LOCAL_LDLIBS := -L$(SYSROOT)/../usr/lib -llog
LOCAL_LDLIBS += -L$(LOCAL_PATH)/lib/support_lib1
LOCAL_LDLIBS += -L$(LOCAL_PATH)/lib/support_lib2
include $(BUILD_SHARED_LIBRARY)
Run Code Online (Sandbox Code Playgroud)
这构建得很好,但是当我尝试运行时,我得到错误,表明dlopen(libnative_lib)失败,因为它无法加载libsupport_lib1.
来到这里我发现了这个:
这说我需要在所有必要的库上调用load库.大!
尝试#2首先打开每个库
static {
System.loadLibrary("support_lib1");
System.loadLibrary("support_lib2");
System.loadLibrary("native_lib");
}
Run Code Online (Sandbox Code Playgroud)
再次,这构建得很好,但是当我运行时,我得到一个新的错误:
无法加载libsupport_lib1.findLibrary返回null.
现在我们到了某个地方.它不能将库加载到目标.
尝试#3将.so文件复制到project/libs/armeabi中
没工作.当Eclipse构建时,它删除了我放在那里的文件.
尝试#4为每个库创建一个新模块
那么我发现了这个:
它是关于静态库的,但也许我遇到了类似的问题.要点是我需要为每个库声明一个模块.所以我的新Android.mk看起来像这样:
LOCAL_PATH := $(call my-dir)
#get support_lib1
include $(CLEAR_VARS)
LOCAL_MODULE := support_lib1
LOCAL_SRC_FILES := $(LOCAL_PATH)/lib/support_lib1.so
include $(BUILD_SHARED_LIBRARY)
#get support_lib2
include $(CLEAR_VARS)
LOCAL_MODULE := support_lib2
LOCAL_SRC_FILES := $(LOCAL_PATH)/lib/support_lib2.so
include $(BUILD_SHARED_LIBRARY) …Run Code Online (Sandbox Code Playgroud) java-native-interface linker android shared-libraries android-ndk
我正在移植Box2D以学习更多关于android移植的知识.
我可以编译项目,我看到以下....
ls libs /
armeabi armeabi-v7a
现在我想要做像这样,但我不知道如何使它足够聪明,选择拱(说我想补充的x86).如何在没有硬编码规范拱的.so路径的情况下包含.so?
我成功编译库LibXtract到共享对象libxtract.so并想在第二个项目中使用.
在提及项目中,我尝试在简单的函数上编译它:
#include <com_androidnative1_NativeClass.h>
#include <android/log.h>
#include "libxtract.h"
JNIEXPORT void JNICALL Java_com_androidnative1_NativeClass_showText
(JNIEnv *env, jclass clazz)
{
float mean = 0, vector[] = {.1, .2, .3, .4, -.5, -.4, -.3, -.2, -.1}, spectrum[10];
int n, N = 9;
float argf[4];
argf[0] = 8000.f;
argf[1] = XTRACT_MAGNITUDE_SPECTRUM;
argf[2] = 0.f;
argf[3] = 0.f;
xtract[XTRACT_MEAN]((void *)&vector, N, 0, (void *)&mean);
__android_log_print(ANDROID_LOG_DEBUG, "LIbXtract", "Button pushe2");
}
Run Code Online (Sandbox Code Playgroud)
我有扁平结构:
library libxtract.so我放入了mainproject/lib文件夹
我的Android.mk文件如下所示:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := …Run Code Online (Sandbox Code Playgroud) 我有一个来自供应商的 .so 文件,它只支持“arm”。目前它非常适合我的 Android 应用程序。不知何故,我想使用 Android Studio 模块分离实现,因此我可以按照本教程https://www.youtube.com/watch?v=1i4I-Nph-Cw将模块导出为 Jar 。
当我导出 JAR 时,构建过程返回错误
/Users/zoom/android-ndk-r9d/toolchains/mipsel-linux-android-4.8/prebuilt/darwin-x86_64/bin/../lib/gcc/mipsel-linux-android/4.8/../../../../mipsel-linux-android/bin/ld: skipping incompatible src/main/jniLibs/armeabi/libremote_client.so when searching for -lremote_client
/Users/zoom/android-ndk-r9d/toolchains/mipsel-linux-android-4.8/prebuilt/darwin-x86_64/bin/../lib/gcc/mipsel-linux-android/4.8/../../../../mipsel-linux-android/bin/ld: cannot find -lremote_client
collect2: error: ld returned 1 exit status
:app:linkMipsDebugRemoteDesktopSharedLibrary FAILED
FAILURE: Build failed with an exception.
Run Code Online (Sandbox Code Playgroud)
日志说 gradle 试图针对 mips 进行构建,但由于库不兼容而失败,因为我只有 arm 库。我的问题是如何跳过针对 mips 的构建过程?或者是否可以仅针对 ARM 架构?
构建.gradle
apply plugin: 'com.android.model.library'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "22.0.1"
defaultConfig.with {
//applicationId = "com.test.remote"
minSdkVersion.apiLevel = 19
targetSdkVersion.apiLevel = 21
//versionCode = …Run Code Online (Sandbox Code Playgroud) android android-ndk android-gradle-plugin gradle-experimental
我目前正在开发一个将使用预构建共享库的项目。但我对导入预构建库以及从新项目 java 类调用预构建库中的方法的过程感到非常困惑。
比方说:
项目 A 已为每个 ABI_ARCH 生成了 libA.so 文件。
我正在尝试在我的项目 B 中使用它们。
导入它们的正确方法是什么,以及如何调用 A 中声明的 libA.so 的方法。换句话说,如何使用 libA.so 公开的 API?
我已经.so在Linus上通过C++ 生成了一个文件并且.so现在生成了文件我已经交叉编译了这个.so文件,Android ARM所以我必须通过它来编辑它Android NDK以便.so
在我的android项目中使用新的genrated .
所以任何人都可以帮助我在我的Android项目中放置Linux生成的.so文件以及在Make文件(Android.mk)中添加什么内容,以便它可以.so使用我之前生成的Linux文件中的现有方法生成新.so文件.
我希望我的问题清楚,如果不是,请告诉我.
请帮我.提前致谢