2012-03-26 25 views
0

问题是JNI中着名的参数传递问题。JNI:使用原始数据类型的包装类型来模拟C++中的指针传递

我想包装一个C++代码,通过指针 和 传递原始参数我只想确认一件事情,以确保Wrapper类不能用于我的问题。

大家都知道像字节(字节模式)和基于整数(对于int)不支持setter方法的包装类型,所以我不能用它来设置一个通行证值使用二传手对象,

但是,赋值运算符呢?

有没有什么办法可以在C++代码中使用JNI调用Wrapper Type“Byte”的赋值运算符(=)?

想法的codeed示例如下:

JNIEXPORT void JNICALL 
Java_InstanceMethodCall_nativeMethod(JNIEnv *env, jobject obj/*A Byte object*/) 
{ 
    jclass cls = (*env)->GetObjectClass(env, obj); 
    jmethodID mid = (*env)->GetMethodID(env, cls, "=(or something else you can tell me)", "(B)V"); 
    if (mid == NULL) { 
     return; /* method not found */ 
    } 
    (*env)->CallVoidMethod(env, obj, mid); 
} 

回答

0

是的,你可以查看或设置的原始框的私人“值”字段中的本地代码。但是,由于该字段是私有的,因此不保证该字段在所有虚拟机实施中都存在。你也受到解释器的控制,它假定关于所传递的值保持不变(在概念上类似于改变标记为“* const”的指针后面的内容)。

你最好传递一个长度为1的基本数组,固定数组并获得相应的指针,以用作要改变的基元的“地址”。

+0

对不起再次问我的问题。我知道Java在运算符操作上比C++更受限制,但是你可以证实这一点:对赋值运算符(=)的访问是公开的(也许它不能从JNI访问,但是在Java中使用它在Byte变量上是公开的)。请确认是否可以从JNI内部调用赋值运算符。 – Taheri 2012-03-27 10:41:48

+0

本身没有赋值“运算符”,在Java中也没有专用的“运算符”函数。正如Chuck Fricano所述,在JNI中,您必须从类对象中获取字段ID,然后使用该ID和对象引用来使用JNI函数SetXXXField()设置字段值。转换字节<->字节称为自动装箱,通常不受您的控制。 – technomage 2012-03-27 12:48:35

+0

请注意,表达式“Byte b = new Byte('b')”只是将新对象分配给对象引用“b”。它*不*改变Byte对象的基础值。基于原语的对象(Byte,Short,Integer等)是不可变的。 – technomage 2012-03-27 12:53:44

0

这里是一个指导性的例子,展示了如何改变一个不可变的对象。你应该认真思考这个问题,最后你不应该这样做。

native void nativeModifyByte(Byte b); 

JNIEXPORT void JNICALL Java_nativeModifyByte(JNIEnv * env, jobject o, jobject b) { 
    jclass c = (*env)->GetObjectClass(env, b); 
    jfieldID fid = (*env)->GetFieldID(env, c, "value", "B"); 
    jbyte oldVal = (*env)->GetByteField(env, b, fid); 
    (*env)->SetByteField(env, b, fid, 42); 
} 

用法:

byte v = 13; 
    Byte b = new Byte(v); 
    nativeModifyByte(b); 
    System.out.println(b); 

输出:

42 
相关问题