簡體   English   中英

JNI:轉換后將基本類型轉換為Jobject或對象類型的SetObjectArrayElement

[英]JNI : convert Primitive type to jobject Or SetObjectArrayElement of Object type after casting

我有以下代碼返回填充有原始類型的struct元素的Object Array,我不知道如何將原始類型轉換為jobject,然后使用SetObjectArrayElement方法設置為ObjectArray,

這是我的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]; };

我的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;      }

我得到的錯誤是

 A fatal error has been detected by the Java Runtime Environment:

SIGSEGV(0xb),位於pc = 0x010290e5,pid = 4754,tid = 4152195952

JRE版本:7.0_09-b05 Java VM:Java HotSpot(TM)客戶端VM(23.5-b02混合模式linux-x86)問題框架:V [libjvm.so + 0x2a80e5] jni_SetObjectArrayElement + 0x1c5

無法寫入核心轉儲。 核心轉儲已被禁用。 要啟用核心轉儲,請在再次啟動Java之前嘗試“ ulimit -c unlimited”

包含更多信息的錯誤報告文件將另存為:/DATA1/home/user1/Myname/myproject/hs_err_pid4754.log

如果您想提交錯誤報告,請訪問: http : //bugreport.sun.com/bugreport/crash.jsp

我的問題是

  1. 我可以像上面一樣返回對象數組
  2. 如果是,如何將原始類型轉換為Jobject

上面的JNI代碼有什么問題.... ??? 謝謝...

您不能僅通過轉換為jobject C ++完全不了解Java自動裝箱。 您將需要手動實例化適當的java對象。

例如, irno需要轉換為java Long類的實例(假設使用64位OS)。 為此,您需要:

  1. 使用FindClass找到Long類的標識符
  2. 找到其構造函數的標識符,該構造函數長時間使用GetMethodID接受原始類型
  3. 通過使用NewObjectAirno作為參數傳遞給其構造函數來創建新的Java Long對象

其他變量必須轉換為它們相應的Java類型:c ++ double到java Double,c ++ char []到java String或java char [],依此類推。

如果您要在Java和Java之間傳遞大量此類原始對象,那么建議您使用一些序列化庫,例如google protobuf。 您用Java填寫protobuf消息,將其序列化為字節數組,然后將此字節數組傳遞給Java。 在Java中,您可以反序列化它並獲得漂亮的Java對象。 當您需要添加更多字段時,則無需再編寫任何容易出錯的JNI代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM