调用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和string。

所以看起来像这样:

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

test

要进行简短的测试,我们可以编写一个呼叫本机C函数的类,该类别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

最新更新