オブジェクトを作成するために、JNI関数を呼び出します

いくつかの名前:

私はC11でJNIスタッフを書き込み、オンヒープオブジェクトの生成に厳密に準拠について質問がありますよ。

JNI APIは、次のシグネチャでこれを行うための機能を提供します。

jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...);

で指定されているように6.5.2.2(p7)、標準

関数プロトタイプ宣言子で省略記号表記は、最後の宣言されたパラメータの後に停止する引数の型変換が発生します。

省略表記に対応する引数は、明示的に適合されるコードのために予想される型に変換されなければなりません。以下のケースを考えてみます。

public class Event{
    public final int eventType;
    public final String meta;

    public Event(int eventType, String meta){
        this.eventType = eventType;
        this.meta = meta;
    }
}

引数のどのような種類の私はに省略記号に対応するパラメータを変換する必要がありますか?

私は次のようになりますことを推測することができます。

jclass event_class = ((*env)->FindClass)(env, "f/q/c/n/Event");
jmethodID ctor = (*env)->GetMethodID(
    env, 
    event_class, 
    "<init>", 
    "(ILjava/lang/String;)V"
);
array_element = (*env)->NewObject(
    env, 
    event_class, 
    ctor, 
    (jint) 0, (jobject) NULL //corresponds to the ellipsis
);
ステファン悪いです:

引数の型は、あなたが呼び出しているメソッドから推定されています。

あなたのケースでは、それはint型と文字列を期待Eventクラスのコンストラクタです。

だから、次のようになります。

jstring metaStr = (*env)->NewStringUTF(env, "hello");

jobject array_element = (*env)->NewObject(
        env,
        event_class,
        ctor,
        (jint)4711, metaStr
);

テスト

簡単なテストを実行するために、我々は、希望Eventオブジェクトを作成するネイティブC関数を呼び出し、それを初期化し、呼び出すJava側に戻り、それをクラスを書くことができます。

このJavaプログラムは次のようになります。

import f.q.c.n.Event;

public class JNIEventTest {

    static {
        System.loadLibrary("native");
    }

    private native Event retrieveNativeEvent();


    public static void main(String[] args) {
        JNIEventTest jniEventTest = new JNIEventTest();
        Event event = jniEventTest.retrieveNativeEvent();
        System.out.println("eventType: " + event.eventType);
        System.out.println("meta: " + event.meta);
    }
}

ネイティブC側は次のようになります。

#include "JNIEventTest.h"

JNIEXPORT jobject JNICALL Java_JNIEventTest_retrieveNativeEvent(JNIEnv *env, jobject thisObject) {


    jclass event_class = ((*env)->FindClass)(env, "f/q/c/n/Event");
    jmethodID ctor = (*env)->GetMethodID(
            env,
            event_class,
            "<init>",
            "(ILjava/lang/String;)V"
    );

    jstring eventStr = (*env)->NewStringUTF(env, "hello");

    jobject array_element = (*env)->NewObject(
            env,
            event_class,
            ctor,
            (jint)4711, eventStr
    );

    return array_element;
}

コンソールでのデバッグ出力は、次のようになります。

eventType: 4711
meta: hello

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=213759&siteId=1