简体   繁体   English

使用JNI从Android调用预构建的C ++共享库

[英]Call prebuilt C++ shared library from Android with JNI

I want to use a prebuilt C++ library from Android via JNI. 我想通过JNI使用Android的预构建C ++库。 Therefore I am working with Android Studio. 因此,我正在使用Android Studio。

I am building the project with com.android.tools.build:gradle-experimental:0.7.0-alpha4 and my build.gradle looks like this: 我正在使用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'
}

I created a wrapper C library to call the prebuilt library from there. 我创建了一个包装器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");
}

My Java class for the wrapper: 包装的我的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");
    }

}

I have created a test-method in my shared library (C++) which looks like this: 我在共享库(C ++)中创建了一个测试方法,如下所示:

int AndroidRexxStart()
{
    return 1;
}

Everything is working fine, and I get the response from my wrapper c library. 一切工作正常,我从包装器c库获得响应。 Now I want to call a function AndroidRexxStart() of the prebuilt library librexx.so in my wrapper library and I do not know how to do that. 现在,我想在包装库中调用预构建库librexx.so的函数AndroidRexxStart() ,但我不知道该怎么做。 What I have to include and how can I call the method? 我必须包含的内容以及如何调用该方法?

EDIT: My Projectstructure: 编辑:我的项目结构: 在此处输入图片说明

You've made a Java wrapper for the library but you also need to make a JNI wrapper for the Java to call. 您已经为该库制作了Java包装器,但还需要为Java调用制作JNI包装器。 So you'll need JNI methods for each of the library methods you want to call. 因此,您需要为要调用的每个库方法使用JNI方法。 I don't know what LibRexx is so I don't know what you would want to call but you just need to expose those in JNI so they can be called from Java. 我不知道LibRexx是什么,所以我不知道您想调用什么,但是您只需要在JNI中公开它们即可从Java调用它们。

First, you're rexxWrapper should be linking in librexx so you shouldn't need to load it in Java. 首先,您是rexxWrapper应该在librexx中链接,因此您不需要在Java中加载它。 Second you can just create another JNI method like this: 其次,您可以仅创建另一个JNI方法,如下所示:

JNIEXPORT jint JNICALL Java_org_oorexx_oorexxforandroid_jniwrapper_RexxWrapper_start(JNIEnv *env, jobject instance) {

    return AndroidRexxStart();
}

Then in your AndroidRexxStart() you would actually call into the librexx to start it. 然后,在您的AndroidRexxStart()您实际上将调用librexx来启动它。

In Java you'll add: 在Java中,您将添加:

private native String start();

to call the JNI method. 调用JNI方法。 The naming of the JNI method is important. JNI方法的命名很重要。 It has to match the Java path, class and method name that you want to use. 它必须与您要使用的Java路径,类和方法名称匹配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM