Android
Android Java Native Interface (JNI)
Zoeken…
Invoering
JNI (Java Native Interface) is een krachtige tool waarmee Android-ontwikkelaars de NDK kunnen gebruiken en C ++ native code in hun applicaties kunnen gebruiken. Dit onderwerp beschrijft het gebruik van de Java <-> C ++ interface.
Functies in een native bibliotheek oproepen via de JNI-interface
Met de Java Native Interface (JNI) kunt u native functies aanroepen vanuit Java-code en vice versa. Dit voorbeeld laat zien hoe een native functie via JNI kan worden geladen en aangeroepen, deze gaat niet in op toegang tot Java-methoden en velden vanuit native code met behulp van JNI-functies .
Stel dat u een native bibliotheek met de naam libjniexample.so
in de map project/libs/<architecture>
hebt en dat u een functie uit de JNITest
Java-klasse in het pakket com.example.jniexample
.
Verklaar in de klasse JNITest de functie als volgt:
public native int testJNIfunction(int a, int b);
Definieer de functie in uw eigen code als volgt:
#include <jni.h>
JNIEXPORT jint JNICALL Java_com_example_jniexample_JNITest_testJNIfunction(JNIEnv *pEnv, jobject thiz, jint a, jint b)
{
return a + b;
}
Het argument pEnv
is een verwijzing naar de JNI-omgeving die u kunt doorgeven aan JNI-functies voor toegang tot methoden en velden van Java-objecten en -klassen. De thiz
aanwijzer is een jobject
naar het Java-object waarnaar de native methode is aangeroepen (of de klasse als het een statische methode is).
Laad de bibliotheek in uw Java-code in JNITest
als volgt:
static{
System.loadLibrary("jniexample");
}
Let op de lib
aan het begin en de .so
aan het einde van de bestandsnaam worden weggelaten.
Roep de native functie van Java als volgt aan:
JNITest test = new JNITest();
int c = test.testJNIfunction(3, 4);
Hoe een Java-methode aan te roepen vanuit native code
Met de Java Native Interface (JNI) kunt u Java-functies aanroepen vanuit native code. Hier is een eenvoudig voorbeeld van hoe het te doen:
Java-code:
package com.example.jniexample;
public class JNITest {
public static int getAnswer(bool) {
return 42;
}
}
Native code:
int getTheAnswer()
{
// Get JNI environment
JNIEnv *env = JniGetEnv();
// Find the Java class - provide package ('.' replaced to '/') and class name
jclass jniTestClass = env->FindClass("com/example/jniexample/JNITest");
// Find the Java method - provide parameters inside () and return value (see table below for an explanation of how to encode them)
jmethodID getAnswerMethod = env->GetStaticMethodID(jniTestClass, "getAnswer", "(Z)I;");
// Calling the method
return (int)env->CallStaticObjectMethod(jniTestClass, getAnswerMethod, (jboolean)true);
}
JNI methode handtekening naar Java type:
JNI-handtekening | Java-type |
---|---|
Z | boolean |
B | byte |
C | verkolen |
S | kort |
ik | int |
J | lang |
F | vlotter |
D | dubbele |
L volledig gekwalificeerde klasse; | volledig gekwalificeerde-klasse |
[type | type[] |
Dus voor ons voorbeeld hebben we (Z) I gebruikt - wat betekent dat de functie een Boolean krijgt en een int retourneert.
Hulpprogramma methode in JNI-laag
Deze methode zal helpen om de Java-string van de C ++ string te krijgen.
jstring getJavaStringFromCPPString(JNIEnv *global_env, const char* cstring) {
jstring nullString = global_env->NewStringUTF(NULL);
if (!cstring) {
return nullString;
}
jclass strClass = global_env->FindClass("java/lang/String");
jmethodID ctorID = global_env->GetMethodID(strClass, "<init>",
"([BLjava/lang/String;)V");
jstring encoding = global_env->NewStringUTF("UTF-8");
jbyteArray bytes = global_env->NewByteArray(strlen(cstring));
global_env->SetByteArrayRegion(bytes, 0, strlen(cstring), (jbyte*) cstring);
jstring str = (jstring) global_env->NewObject(strClass, ctorID, bytes,
encoding);
global_env->DeleteLocalRef(strClass);
global_env->DeleteLocalRef(encoding);
global_env->DeleteLocalRef(bytes);
return str;
}
Deze methode helpt je om jbyteArray naar char te converteren
char* as_unsigned_char_array(JNIEnv *env, jbyteArray array) {
jsize length = env->GetArrayLength(array);
jbyte* buffer = new jbyte[length + 1];
env->GetByteArrayRegion(array, 0, length, buffer);
buffer[length] = '\0';
return (char*) buffer;
}