Verwendung von JNI für die Kommunikation zwischen JAVA und C++ (Qt JNI Messenger-Beispieleinführung) – Android-Entwicklung, Qt

Vorwort

Die Verwendung von Qt zur Entwicklung von Android erfordert zwangsläufig den Aufruf des zugrunde liegenden Codes, dh den Aufruf der Java-Funktion, die JNI verwendet.

JNI-Grundwissenspunkte

Schlüsselwörter nativ

Das native Schlüsselwort gibt an, dass es sich bei der geänderten Methode um eine native Methode handelt. Die entsprechende Implementierung der Methode befindet sich nicht in der aktuellen Datei (dh sie wird nur hier deklariert), sondern in Dateien, die in anderen Sprachen (z. B. C usw.) implementiert sind C++) . Die Java-Sprache selbst kann nicht auf das zugrunde liegende Betriebssystem zugreifen und es betreiben, kann jedoch über die JNI-Schnittstelle andere Sprachen aufrufen, um Zugriff auf die zugrunde liegende Schicht zu erhalten.

jobject, jclass

Sie können es anhand des Namens erraten: jclass ist die Klasse selbst, jobject ist die Klasseninstanz,

Allgemein:

  • Wenn die in Java definierte native Methode eine statische Methode ist, ist der zweite Parameter jclass, und jclass stellt die Klasse selbst der Klasse dar, zu der die native Methode gehört.
  •  Wenn die in Java definierte native Methode eine nicht statische Methode ist, ist der zweite Parameter jobject, und jobject stellt das Instanzobjekt der Klasse dar, zu der die native Methode gehört.

Weitere Informationen finden Sie im folgenden Artikel:

JNI/NDK-Erste Schritte – jobject und jclass_jni jobject_IT Xiansens Blog-CSDN-Blog

 JNIEnv

JNIEnv ist die Basisumgebung, die native JNI-Funktionen bereitstellt. Sie ist threadbezogen. JNIEnv verschiedener Threads sind unabhängig voneinander. JNIEnv ist ein JNI-Schnittstellenzeiger, der auf eine Funktionstabelle nativer Methoden zeigt . Jedes Mitglied der Funktionstabelle zeigt zu einer JNI-Funktion. Native Methoden greifen über JNI-Funktionen auf Datenstrukturen in der JVM zu.

Weitere Informationen finden Sie im folgenden Artikel:

JNI/NDK-Erste-Schritte-Leitfaden: JavaVM und JNIEnv_javavm jni_IT Xiansens Blog-CSDN-Blog

JNINativeMethod

JNINativeMethod Diese Struktur wird verwendet, um die Informationen zur nativen JNI-Methode zu beschreiben, die registriert werden müssen. Übergeben Sie es in der Registrierungsfunktionstabelle JNIEnv::RegisterNatives.

    jint RegisterNatives(jclass clazz, const JNINativeMethod* methods,
        jint nMethods)

Bitte lesen Sie den folgenden Artikel, um zu erfahren, wie Sie es verwenden:

JNINativeMethod von JNI – Android_Ten Years Less Blog-CSDN-Blog

verwenden

Profil

QT += androidextras

Java ruft C++ auf

Definieren Sie native Methoden im Java-Code

package org.qtproject.example.jnimessenger;

public class JniMessenger
{
    //用 native 声明的方法表示告知 JVM 调用,该方法在外部定义,一个native Method就是一个 Java 调用非 Java 代码的接口。
    private static native void callFromJava(String message);

    public JniMessenger() {}

    public static void printFromJava(String message)
    {
        System.out.println("This is printed from JAVA, message is: " + message);

       //这里调用了native方法(外部实现的)
        callFromJava("Hello from JAVA!");
    }
}

In C++ implementiert: Hier wird die C++-JniMessenger-Instanz aufgerufen, um das Signal messageFromJava auszugeben, und das Signal wird als Parameterwert übergeben. Die in C++ definierten Implementierungen liegen alle in diesem Format vor

 static 【return】 funcName (JNIEnv *env, jclass ,【arg1,arg2 ...】) Wird angezeigt

【return】 funcName (JNIEnv *env, jobject,【arg1,arg2 ...】)

JniMessenger *JniMessenger::m_instance = nullptr;

static void callFromJava(JNIEnv *env, jclass /*thiz*/, jstring value)

{
    emit JniMessenger::instance()->messageFromJava(env->GetStringUTFChars(value, nullptr));
}

 Konvertieren Sie jstring in char* 

const char* GetStringUTFChars(jstring string, jboolean* isCopy) 

 Das Obige ist ein in C++ implementierter Aufruf von Java. Wenn Sie ihn jedoch mit Java verknüpfen möchten, müssen Sie diesen Funktionszeiger auch in JNIEnv registrieren. Wie in den Grundkenntnissen oben erwähnt, ist „JNIEnv ein JNI-Schnittstellenzeiger, der auf eine Funktion zeigt.“ einer lokalen Methode . Table , müssen wir diese Funktion in dieser Funktionstabelle registrieren

JniMessenger::JniMessenger(QObject *parent) : QObject(parent)
{
    m_instance = this;

   //c++ 本地定义的 jni native方法
    JNINativeMethod methods[] {
   
   {"callFromJava", "(Ljava/lang/String;)V", reinterpret_cast<void *>(callFromJava)}};

    QAndroidJniObject javaClass("org/qtproject/example/jnimessenger/JniMessenger");

   //注册
    QAndroidJniEnvironment env;
    jclass objectClass = env->GetObjectClass(javaClass.object<jobject>());
    env->RegisterNatives(objectClass,
                         methods,
                         sizeof(methods) / sizeof(methods[0]));
    //释放内存
    env->DeleteLocalRef(objectClass);
}

 

C++ ruft Java auf

Es ist relativ einfach, Java-Funktionen in C++ wie folgt aufzurufen

Beispiel für eine statische Funktion:

void JniMessenger::printFromJava(const QString &message)
{
    QAndroidJniObject javaMessage = QAndroidJniObject::fromString(message);
    QAndroidJniObject::callStaticMethod<void>("org/qtproject/example/jnimessenger/JniMessenger", //类名
                                       "printFromJava",//函数名
                                       "(Ljava/lang/String;)V",//(参数类型)返回类型
                                        javaMessage.object<jstring>());//传入参数
}

Beispiel für eine gewöhnliche Funktion (wenn printFromJava in Java definiert ist, ist es eine gewöhnliche Funktion):

void JniMessenger::printFromJava(const QString &message)
{
    QAndroidJniObject javaMessage = QAndroidJniObject::fromString(message);

    QAndroidJniObject javaClass("org/qtproject/example/jnimessenger/JniMessenger");
    javaClass.callObjectMethod("printFromJava",
                               "(Ljava/lang/String;)V",
                                javaMessage.object<jstring>());
}

 

Abschluss

Dies ist erst der Anfang. Wer mit Android spielen möchte, muss noch das gesamte Framework erlernen bzw. verstehen.

おすすめ

転載: blog.csdn.net/xiaopei_yan/article/details/130884889