[英]JNI : convert Primitive type to jobject Or SetObjectArrayElement of Object type after casting
I'm have following code to return Array of Object Array filled with struct elements of primitive types , I don't know how to convert primitive types to jobject, and then set to ObjectArray using SetObjectArrayElement method, 我有以下代码返回填充有原始类型的struct元素的Object Array,我不知道如何将原始类型转换为jobject,然后使用SetObjectArrayElement方法设置为ObjectArray,
Here is my C struct info 这是我的C结构信息
struct cheqdtl {
unsigned long irno;
char bank_accno1 [16];
unsigned long bank_id;
unsigned long outlet_id;
char bank_accno [16];
char cheque_num [41];
double deposit_amt;
char chq_date [4]; };
My JNI code 我的JNI代码
JNIEXPORT jobjectArray JNICALL Java_nativeclass_Jmain_getChequeList (JNIEnv *env,jobject jobj,jint ch,jstring benAccNo,jstring fromDate,jstring toDate){
clientlist *cl = new clientlist();
ShortInt lcount = 0;
int i;
jmp_buf jmpb;
const char *ben_acc_no = env->GetStringUTFChars(benAccNo, NULL);
const char *from_date = env->GetStringUTFChars(fromDate, NULL);
const char *to_date = env->GetStringUTFChars(toDate, NULL);
struct b_date f_date, t_date;
char temp_date[10];
mov_mem((char *)from_date, temp_date, 2);
temp_date[2] = '\0';
f_date.day = atoi(temp_date);
mov_mem((char *)from_date + 3, temp_date, 2);
temp_date[2] = '\0';
f_date.month = atoi(temp_date);
mov_mem((char *)from_date+6, temp_date, 4);
temp_date[4] = '\0';
f_date.year = atoi(temp_date);
mov_mem((char *)to_date, temp_date, 2);
temp_date[2] = '\0';
t_date.year = atoi(temp_date);
mov_mem((char *)to_date + 3, temp_date, 2);
temp_date[2] = '\0';
t_date.month = atoi(temp_date);
mov_mem((char *)to_date + 6, temp_date, 4);
temp_date[4] = '\0';
t_date.year = atoi(temp_date);
struct cheqdtl *cq_dtl = NULL;
cq_dtl = (struct cheqdtl *)malloc( sizeof( struct cheqdtl) );
cl->get_cheque_list((int)ch,(char *)ben_acc_no, &f_date, &t_date, &cq_dtl, &lcount);
jclass objCls= env->FindClass("java/lang/Object");
if( objCls == NULL )
return NULL;
jobjectArray outObjArr = env->NewObjectArray( lcount, objCls, NULL );
jmethodID jobjConstrId = env->GetMethodID( objCls, "<init>", "()V" );
if( jobjConstrId == 0)
return NULL;
jobjectArray rowObjArr ;
if( !lcount )
return NULL;
for( i = 0; i < lcount; ++i ) {
rowObjArr = env->NewObjectArray(8, objCls, NULL);
cout<<"\n Get Array Length:- "<<env->GetArrayLength(rowObjArr)<<endl;
std::cout<<cq_dtl[i].irno<<"\n";
std::cout<<cq_dtl[i].bank_accno1<<"\n";
std::cout<<cq_dtl[i].bank_id<<"\n";
std::cout<<cq_dtl[i].outlet_id<<"\n";
std::cout<<cq_dtl[i].bank_accno<<"\n";
std::cout<<cq_dtl[i].cheque_num<<"\n";
std::cout<<cq_dtl[i].deposit_amt<<"\n";
std::cout<<cq_dtl[i].chq_date<<"\n";
env->SetObjectArrayElement(rowObjArr, 0, (jobject) cq_dtl[i].irno);
env->SetObjectArrayElement(rowObjArr, 1, (jobject) cq_dtl[i].bank_accno1);
env->SetObjectArrayElement(rowObjArr, 2, (jobject) cq_dtl[i].bank_id);
env->SetObjectArrayElement(rowObjArr, 3, (jobject) cq_dtl[i].outlet_id);
env->SetObjectArrayElement(rowObjArr, 4, (jobject) cq_dtl[i].bank_accno);
env->SetObjectArrayElement(rowObjArr, 5, (jobject) cq_dtl[i].cheque_num);
env->SetObjectArrayElement(rowObjArr, 6, (jobject) cq_dtl[i].deposit_amt);
env->SetObjectArrayElement(rowObjArr, 7, (jobject) cq_dtl[i].chq_date);
if( rowObjArr )
env->SetObjectArrayElement( outObjArr, i, rowObjArr );
env->DeleteLocalRef( rowObjArr );
}
env->DeleteLocalRef( objCls );
free( cq_dtl );
delete cl;
return outObjArr; }
The Error I got is 我得到的错误是
A fatal error has been detected by the Java Runtime Environment:
SIGSEGV (0xb) at pc=0x010290e5, pid=4754, tid=4152195952 SIGSEGV(0xb),位于pc = 0x010290e5,pid = 4754,tid = 4152195952
JRE version: 7.0_09-b05 Java VM: Java HotSpot(TM) Client VM (23.5-b02 mixed mode linux-x86 ) Problematic frame: V [libjvm.so+0x2a80e5] jni_SetObjectArrayElement+0x1c5 JRE版本:7.0_09-b05 Java VM:Java HotSpot(TM)客户端VM(23.5-b02混合模式linux-x86)问题框架:V [libjvm.so + 0x2a80e5] jni_SetObjectArrayElement + 0x1c5
Failed to write core dump. 无法写入核心转储。 Core dumps have been disabled.
核心转储已被禁用。 To enable core dumping, try "ulimit -c unlimited" before starting Java again
要启用核心转储,请在再次启动Java之前尝试“ ulimit -c unlimited”
An error report file with more information is saved as: /DATA1/home/user1/Myname/myproject/hs_err_pid4754.log 包含更多信息的错误报告文件将另存为:/DATA1/home/user1/Myname/myproject/hs_err_pid4754.log
If you would like to submit a bug report, please visit: http://bugreport.sun.com/bugreport/crash.jsp 如果您想提交错误报告,请访问: http : //bugreport.sun.com/bugreport/crash.jsp
My questions are 我的问题是
What is wrong with above JNI code ....??? 上面的JNI代码有什么问题.... ??? Thank you...
谢谢...
You can't achieve this by simply converting to jobject
. 您不能仅通过转换为
jobject
。 C++ has absolutely no knowledge of java autoboxing. C ++完全不了解Java自动装箱。 You will need to instantiate appropriate java objects manually.
您将需要手动实例化适当的java对象。
For example, irno
needs to be converted to instance of java Long class (assuming 64-bit OS). 例如,
irno
需要转换为java Long类的实例(假设使用64位OS)。 In order to do so, you need: 为此,您需要:
irno
as argument to its constructor with NewObjectA irno
作为参数传递给其构造函数来创建新的Java Long对象 Other variables must be converted to their corresponding java types: c++ double to java Double, c++ char[] to java String or to java char[] and so on. 其他变量必须转换为它们相应的Java类型:c ++ double到java Double,c ++ char []到java String或java char [],依此类推。
If you are going to pass a lot of such primitive objects to and from java, then I suggest that you use some serialization library, such as google protobuf. 如果您要在Java和Java之间传递大量此类原始对象,那么建议您使用一些序列化库,例如google protobuf。 You fill in protobuf message in java, serialize it into byte array and pass this byte array into java.
您用Java填写protobuf消息,将其序列化为字节数组,然后将此字节数组传递给Java。 In java, you deserialize it and get nice java object.
在Java中,您可以反序列化它并获得漂亮的Java对象。 When you need to add more fields, then you won't need to write any more error-prone JNI code.
当您需要添加更多字段时,则无需再编写任何容易出错的JNI代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.