我正在写在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和字符串事件类的构造函数。
因此,它是这样的:
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
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句