【问题标题】:Android NDK - How to function call another prebuilt libraryAndroid NDK - 如何调用另一个预建库
【发布时间】:2014-08-01 20:59:26
【问题描述】:

我有一个预建的 .so 文件,我的 Android.mk 是:

LOCAL_MODULE    := hello
LOCAL_SRC_FILES := libfoo.so hello.c
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
include $(BUILD_SHARED_LIBRARY)

现在,我想要的是如何构建 hello.c ,它调用一个函数(getBoo - 位于 libfoo.so 中)文件

我目前拥有的是:

#include <jni.h>

jstring Java_com_example_getBoo( JNIEnv*  env,jobject  this,jstring x )
{
    return foo.getBoo(x);
}

显然没有引用 libfoo.so 文件,我该如何解决这个问题?

【问题讨论】:

  • 一种简单的方法是让您的 Java 代码先加载另一个库。

标签: c android-ndk java-native-interface ndk-build


【解决方案1】:

Android.mk

LOCAL_PATH      := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := hello
LOCAL_SRC_FILES := hello.c
LOCAL_SHARED_LIBRARIES := foo_prebuilt
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := foo_prebuilt
LOCAL_SRC_FILES := libfoo.so
include $(PREBUILT_SHARED_LIBRARY)

不要忘记您的 Java 代码应该以正确的顺序加载这两个库:

System.loadLibrary("foo");
System.loadLibrary("hello");

你还需要函数声明来满足 C 编译器的要求。

#include <jni.h>
extern int getBoo(int);

jint Java_com_example_getBoo(JNIEnv* env, jobject this, jint x)
{
    return getBoo(x);
}

我希望您知道 libfoo.so 中导出函数的名称。无论如何,NDK (ndk\toolchains\arm-linux-androideabi-4.8\prebuilt\windows-x86_64\bin\arm-linux-androideabi-nm.exe) 中有 nm 命令。用-D 运行它,你就有了这个列表。通常,我们使用与用于提供前向声明的库一起提供的头文件。

我看到您的原始示例打算采用字符串参数并返回字符串。这增加了另一个层次的复杂性,请阅读 JNI 书籍,了解 JNI 如何处理 Java 字符串。

【讨论】:

  • 很好,但是我如何在 C 中调用该函数?总是为我返回“未知类型名称 foo”
  • 你不需要“foo”。字首。链接器会发现 getBoo() 在该库中实现。您需要在 C 代码中声明函数,请参阅更新(注释格式不允许代码示例)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-05
  • 2011-07-15
  • 2015-12-15
  • 1970-01-01
  • 2011-11-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多