【问题标题】:Call prebuilt C++ shared library from Android with JNI使用 JNI 从 Android 调用预构建的 C++ 共享库
【发布时间】:2016-08-04 00:42:50
【问题描述】:

我想通过 JNI 使用来自 Android 的预构建 C++ 库。因此,我正在使用 Android Studio。

我正在使用 com.android.tools.build:gradle-experimental:0.7.0-alpha4 构建项目,我的 build.gradle 看起来像这样:

apply plugin: "com.android.model.application"

model {
    repositories {
        libs(PrebuiltLibraries) {
            rexxlib {
                binaries.withType(SharedLibraryBinary) {
                    sharedLibraryFile = file("src/main/jniLibs/armeabi/librexx.so")
                }
            }
            rexxapilib {
                binaries.withType(SharedLibraryBinary) {
                    sharedLibraryFile = file("src/main/jniLibs/armeabi/librexxapi.so")
                }
            }
        }
    }



    android {
        compileSdkVersion 23
        buildToolsVersion "23.0.3"

        defaultConfig {
            applicationId "org.oorexx.oorexxforandroid"
            minSdkVersion.apiLevel 19
            targetSdkVersion.apiLevel 23
            versionCode 1
            versionName "1.0"
            buildConfigFields {
                create() {
                    type "int"
                    name "VALUE"
                    value "1"
                }
            }
        }

        ndk {
            moduleName "rexxwrapper"
        }

        buildTypes {
            release {
                minifyEnabled false
                proguardFiles.add(file("proguard-rules.pro"))
            }
        }

        // Configures source set directory.
        sources {
            main {
                java {
                    source {
                        srcDir "src/main/java"
                    }
                }
                jniLibs {
                    dependencies {
                        library "rexxlib"
                        library "rexxapilib"
                    }

                }
            }
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.3.0'
    compile 'com.android.support:design:23.3.0'
}

我创建了一个包装 C 库来从那里调用预构建的库。

#include "org_oorexx_oorexxforandroid_jniwrapper_RexxWrapper.h"
#include <jni.h>

JNIEXPORT jstring JNICALL Java_org_oorexx_oorexxforandroid_jniwrapper_RexxWrapper_callrexx(JNIEnv *env, jobject instance) {

    //TODO: call function of prebuilt library librexx.so - What todo?

    return (*env)->NewStringUTF(env, "Hello From Jni");
}

我的包装器 Java 类:

public class RexxWrapper {

    private native String callrexx();

    static public void execute(String argv[]) {
        RexxWrapper rexxWrapper = new RexxWrapper();
        System.out.println("--> "+rexxWrapper.callrexx());
    }

    static {
        System.loadLibrary("rexx");
        System.loadLibrary("rexxwrapper");
    }

}

我在共享库 (C++) 中创建了一个测试方法,如下所示:

int AndroidRexxStart()
{
    return 1;
}

一切正常,我从我的包装 c 库中得到响应。现在我想在我的包装库中调用预建库librexx.so 的函数AndroidRexxStart(),但我不知道该怎么做。我必须包含什么以及如何调用该方法?

编辑: 我的项目结构:

【问题讨论】:

    标签: java android c++ java-native-interface


    【解决方案1】:

    您已经为库创建了一个 Java 包装器,但您还需要为 Java 调用创建一个 JNI 包装器。因此,对于要调用的每个库方法,您都需要 JNI 方法。我不知道 LibRexx 是什么,所以我不知道你想调用什么,但你只需要在 JNI 中公开它们,以便可以从 Java 调用它们。

    首先,您的 rexxWrapper 应该在 librexx 中进行链接,因此您不需要在 Java 中加载它。其次,您可以像这样创建另一个 JNI 方法:

    JNIEXPORT jint JNICALL Java_org_oorexx_oorexxforandroid_jniwrapper_RexxWrapper_start(JNIEnv *env, jobject instance) {
    
        return AndroidRexxStart();
    }
    

    然后在您的 AndroidRexxStart() 中,您实际上会调用 librexx 来启动它。

    在 Java 中,您将添加:

    private native String start();
    

    调用JNI方法。 JNI 方法的命名很重要。它必须与您要使用的 Java 路径、类和方法名称相匹配。

    【讨论】:

    • 感谢您的回复 - 我在帖子的共享库中添加了我的测试方法。根据我的例子,也许你可以给我更多的信息。
    • 所以你的意思是我应该可以直接从我的rexxwrapper.c 调用AndroidRexxStart() 函数?
    • 是的。我的意思是,这是一个选择。这将归结为您希望如何组织代码,但这就是想法。
    • 好的 - 因为如果我尝试 gradle 构建会引发错误:Error:(12) undefined reference to 'AndroidRexxStart' - Error:Execution failed for task ':app:linkRexxwrapperArmeabi-v7aDebugSharedLibrary'.
    • 您是否将带有 AndroidRexxStart 的文件包含到您的 JNI 文件中?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-22
    • 1970-01-01
    • 2014-11-10
    • 2018-04-22
    • 2012-09-16
    • 1970-01-01
    • 2015-03-30
    相关资源
    最近更新 更多