JNI对象数组域的赋值问题怎么做?

leishen861 2012-02-07 01:29:30
如果java层有如下定义:
class A{
B[] barray;
}
class B{
int topic;
}
在JNI的底层应该如何去获得一个含有长度为5的B对象数组的A对象呢?
生成B数组可以这样生成:
jclass objectB_Class = (env)->FindClass("B");

jmethodID mid_B = (env)->GetMethodID(objectB_Class,"<init>","()V");

jfieldID B_Id = (env)->GetFieldID(objectB_Class,"topic","I");

jobjectArray B_array = (env)->NewObjectArray((jsize)ARRAY_LENGTH,objectB_Class,0);

int i = 0;

for(;i<ARRAY_LENGTH;i++)
{

jobject B_Object = (env)->NewObject(objectB_Class ,mid_B);

(env)->SetIntField(B_Object ,B_Id ,i);

(env)->SetObjectArrayElement( B_array ,i , B_Object );
}
A对象可以这样生成:
jclass objectA_Class = (env)->FindClass("A");

jmethodID mid_A = (env)->GetMethodID(objectA_Class,"<init>","()V");

jobject A_Object = (env)->NewObject(objectA_Class,mid_A);

但是不知道怎么把B数组赋值到A中,求高人指导!
...全文
306 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
leishen861 2012-02-10
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 nbda1121440 的回复:]
引用 2 楼 leishen861 的回复:

引用 1 楼 abc130314 的回复:
env应该有Get/SetObjectField 的方法

env只有SetObjectField,但是对象A中的成员是B[]类型的,相当于ObjectArray吧。env没有这样的方法。。如果用SetObjectField,会报错。


在java里面数组也是对象,是可以用的
不信你可以……
[/Quote]
谢谢! 终于搞定了。
jfieldID fid_array = (*env)->GetFieldID(env, class_A, "array", "[LB;");
最后一个参数的分号落下了,一个字符一个字符的比啊~ 感激!!!!
周靖峰 2012-02-07
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 leishen861 的回复:]

引用 1 楼 abc130314 的回复:
env应该有Get/SetObjectField 的方法

env只有SetObjectField,但是对象A中的成员是B[]类型的,相当于ObjectArray吧。env没有这样的方法。。如果用SetObjectField,会报错。
[/Quote]

在java里面数组也是对象,是可以用的
不信你可以运行下面的代码

A.java

public class A
{
B[] array;

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

public native void fun(); //用于给数组赋值

public static void main(String[] args)
{
A a = new A();
a.fun();
for (B b : a.array)
{
System.out.println(b.topic);
}
}
}

class B
{
int topic;
}


A.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class A */

#ifndef _Included_A
#define _Included_A
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: A
* Method: fun
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_A_fun
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif


A.c

#include "A.h"

#define ARRAY_LENGTH 10

/*
* Class: A
* Method: fun
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_A_fun
(JNIEnv * env, jobject this_obj)
{
jclass class_B = (*env)->FindClass(env, "B");
jclass class_A = (*env)->FindClass(env, "A");
jfieldID fid_topic = (*env)->GetFieldID(env, class_B, "topic", "I");
jfieldID fid_array = (*env)->GetFieldID(env, class_A, "array", "[LB;");
jmethodID mid_B = (*env)->GetMethodID(env, class_B, "<init>", "()V");
jmethodID mid_A = (*env)->GetMethodID(env, class_A, "<init>", "()V");
jobjectArray obj_arrayB = (*env)->NewObjectArray(env, (jsize) ARRAY_LENGTH, class_B, 0);
int i = 0;

for (; i < ARRAY_LENGTH; i++)
{
jobject obj_B = (*env)->NewObject(env, class_B, mid_B);
(*env)->SetIntField(env, obj_B, fid_topic, i);
(*env)->SetObjectArrayElement(env, obj_arrayB, i, obj_B);
}
(*env)->SetObjectField(env, this_obj, fid_array, obj_arrayB);
}
abc130314 2012-02-07
  • 打赏
  • 举报
回复
我用的SetObjectField,没有问题

public class Main {

public native void g(String[] arr);
private String[] arr;
}


JNIEXPORT void JNICALL Java_dll_1test_Main_g
(JNIEnv *env, jobject this, jobjectArray arr)
{
JNIEnv _env = *env;
jclass clazz = _env->GetObjectClass(env, this);
jfieldID fid = _env->GetFieldID(env, clazz, "arr", "[Ljava/lang/String;");
if (fid == NULL)
{
return;
}
_env->SetObjectField(env, this, fid, arr);
}
leishen861 2012-02-07
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 abc130314 的回复:]
env应该有Get/SetObjectField 的方法
[/Quote]
env只有SetObjectField,但是对象A中的成员是B[]类型的,相当于ObjectArray吧。env没有这样的方法。。如果用SetObjectField,会报错。
abc130314 2012-02-07
  • 打赏
  • 举报
回复
env应该有Get/SetObjectField 的方法

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧