简体   繁体   中英

Call prebuilt C++ shared library from Android with JNI

I want to use a prebuilt C++ library from Android via JNI. Therefore I am working with 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:

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.

#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:

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:

int AndroidRexxStart()
{
    return 1;
}

Everything is working fine, and I get the response from my wrapper c library. 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. 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. So you'll need JNI methods for each of the library methods you want to call. 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.

First, you're rexxWrapper should be linking in librexx so you shouldn't need to load it in Java. Second you can just create another JNI method like this:

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.

In Java you'll add:

private native String start();

to call the JNI method. The naming of the JNI method is important. It has to match the Java path, class and method name that you want to use.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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