java - 仅使用 C 共享库和头文件,使用 JNI 从 Android 调用 C

标签 java android java-native-interface

Android Studio 0.3.1

你好,

我有以下用 C 编写的库,但没有源代码,只有 libapp_module.so

libapp_module.so: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped

我有这个库的头文件:

#ifdef __cplusplus
extern "C" {
#endif

#ifdef _WIN32
#define LIB_API(type) __declspec(dllexport) type
#else 
#define LIB_API(type) type
#endif

LIB_API(int) module_init();

#ifdef __cplusplus
}
#endif

问题是当我尝试从 Android 应用程序调用该函数时出现异常:

D/dalvikvm﹕ Added shared lib /data/app-lib/com.sunsystems.snaptest-1/libapp_module.so 0x416f3d88
D/dalvikvm﹕ No JNI_OnLoad found in /data/app-lib/com.sunsystems.snaptest-1/libapp_module.so 0x416f3d88, skipping init
W/dalvikvm﹕ No implementation found for native Lcom/sunsystems/snaptest/App_Module;.module_init:()I
UnsatisfiedLinkError: Native method not found: com.sunsystems.snaptest.App_Module.module_init:()I

这就是我正在做的事情

我创建了一个 Android 应用程序,我想从我的应用程序中调用 module_init(),因此我创建了一个名为 App_Module.java 的类

public class App_Module {
    /* Load native C libraries */
    static {
        System.loadLibrary("app_module");
    }

    public native static int module_init();
}

我在项目的根目录中使用了这样的 JNI:

javah -jni -classpath build/classes/debug -d jni/ com.sunsystems.snaptest.App_Module

生成了以下 header 接口(interface):

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_sunsystems_snaptest_App_Module */

#ifndef _Included_com_sunsystems_snaptest_App_Module
#define _Included_com_sunsystems_snaptest_App_Module
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_sunsystems_snaptest_App_Module
 * Method:    module_init
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_sunsystems_snaptest_App_Module_module_1init
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

然后在我的 Android 应用程序中,我加载上述 App_Module 类中的库并按如下方式调用它:

App_Module.module_init()

所以我猜它在 libapp_module.so 库中找不到符号。

非常感谢您的建议,

最佳答案

您必须实现 native 方法并使其调用库中的函数。例如:

#include "header_file_for_your_library.h"

#include "com_sunsystems_snaptest_App_Module.h"

JNIEXPORT jint JNICALL Java_com_sunsystems_snaptest_App_Module_module_1init(JNIEnv *env, jclass klass) {
    return module_init();
}

几乎任何有关 JNI 或 Android NDK 的教程都会有更多详细信息。

关于java - 仅使用 C 共享库和头文件,使用 JNI 从 Android 调用 C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19587603/

相关文章:

java - Web View 不显示 HTML

android - 将 sqlite 导出到 csv

serial-port - RS232 FTDI FT_OPEN 返回 FT_ERROR CODE = 3

android - 如何在 Android 中使用 FFMPEG 库播放视频?

java - 如何从驻留在 OSGi 包中的类获取 JNI 中的 jclass

Java - 公共(public)字符串(字符 [] 值)

Java ConstraintValidator 用途

java - java递归创建树

java - Realm 加密导致 Android 中插入速度非常慢

Android:在xml中选择包含 View 的位置