调用JNI函数创建对象

3
我将为您翻译以下内容:

我正在使用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
);
1个回答

1

参数的类型是从您调用的方法中推断出来的。

在您的情况下,它是Event类的构造函数,需要一个int和一个String。

因此,它应该是这样的:

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

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

测试

为了进行简短的测试,我们可以编写一个调用本地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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接