做了两天,用JNI的一点感受

这几天公司在搞一个与第三方的软件结合,公司让我去做。由于原来对VC不是很熟悉,所以做这个的编程痛苦指数是很高的。

这里用了两种方式来做。需求是对本地文件的读取,提取里面的信息。文件是按STRUCT写进去的。所以是在VC里面用CFILE一次读取一个STRUCT,然后再把读到的信息进行处理。

方案(1)

把读到的信息接成一个字符串,返回给JAVA。这里有一个问题,就是编码的问题,CString是用UNICODE编码,JAVA是用UTF-8,在JAVA中无论怎么转换都不行,所以最后是在VC里面多CString进行转换。

转换代码如下:

jstring WindowsTojstring( JNIEnv* env, char* str )
{
    jstring rtn = 0;
    int slen = strlen(str);
    unsigned short * buffer = 0;
    if( slen == 0 )
        rtn = (env)->NewStringUTF(str );
    else
    {
        int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, NULL, 0 );
        buffer = (unsigned short *)malloc( length*2 + 1 );
        if( MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, (LPWSTR)buffer, length ) >0 )
            rtn = (env)->NewString(  (jchar*)buffer, length );
    }
    if( buffer )
        free( buffer );
    return rtn;
}

调用这方法的代码是:

 char * temp=new char();
 temp=str.GetBuffer(str.GetLength());
 jstring sResult=WindowsTojstring(env,temp);

return sResult;

这样返回到JAVA中文就能正确显示了。

方案(2)

返回一个对象数组。

读到一个STRUCT后把数据存到一个对象,这样就能返回一个对象数组。这种方法比较正规,不需要在JAVA里对字符串进行分割。

CString GetIPStr(DWORD ipAddr)
{
 CString sIP;
 in_addr addr;

 addr.S_un.S_addr = ipAddr;
 sIP.Format( "%d.%d.%d.%d",
   addr.S_un.S_un_b.s_b1,
   addr.S_un.S_un_b.s_b2,
   addr.S_un.S_un_b.s_b3,
   addr.S_un.S_un_b.s_b4);

 return sIP;
}

DWORD ip2dw(DWORD dw)
{
 CString sIP;
 in_addr addr;

 addr.S_un.S_addr = dw;
 BYTE b1=addr.S_un.S_un_b.s_b1;
 BYTE b2=addr.S_un.S_un_b.s_b2;
 BYTE b3=addr.S_un.S_un_b.s_b3;
 BYTE b4=addr.S_un.S_un_b.s_b4;
 DWORD ret=b1*256*256*256+b2*256*256+b3*256+b4;


 return ret;
}

jstring WindowsTojstring( JNIEnv* env, char* str )
{
    jstring rtn = 0;
    int slen = strlen(str);
    unsigned short * buffer = 0;
    if( slen == 0 )
        rtn = (env)->NewStringUTF(str );
    else
    {
        int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, NULL, 0 );
        buffer = (unsigned short *)malloc( length*2 + 1 );
        if( MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, (LPWSTR)buffer, length ) >0 )
            rtn = (env)->NewString(  (jchar*)buffer, length );
    }
    if( buffer )
        free( buffer );
    return rtn;
}

JNIEXPORT jobjectArray JNICALL Java_MyCome_getStructArray
  (JNIEnv *env, jobject _obj)
{
 jobjectArray args = 0;
 CFile file;
 int LogSize=sizeof(LOG_MSN);
 LOG_MSN log;
 CString strSQL;
 CString strFMT=_T("insertMSN '%s','%s','%s','%s','%s','%s','%d','%s','%s','%s','%u'");
 CString str="";
 int i=0;//数组长度

 if(file.Open("d://20050708.V04",CFile::modeRead|CFile::shareDenyNone))
 {


  // if(strDate!=_T("") && memcmp(listFile[i],strDate,strlen(listFile[i]))==0)
   // file.Seek(100+pos*LogSize,CFile::begin);
  // else
  int size=file.GetLength();
  i=(size-10)/LogSize;
  file.Seek(100,CFile::begin);
  jclass objClass = (env)->FindClass("java/lang/Object");

  //新建object数组
  args = (env)->NewObjectArray(i, objClass, 0);

  jobjectArray coppy=0;
  coppy=(env)->NewObjectArray(i,objClass,0);

  /**//* 下面为获取到Java中对应的实例类中的变量*/

  //获取Java中的实例类
  jclass objectClass = (env)->FindClass("LOG_MSN");

  jfieldID capTrue = (env)->GetFieldID(objectClass,"tmCapture","Ljava/lang/String;");
  jfieldID user = (env)->GetFieldID(objectClass,"sUser","Ljava/lang/String;");
  jfieldID srcMac = (env)->GetFieldID(objectClass,"sSrcMac","Ljava/lang/String;");
  jfieldID pcName = (env)->GetFieldID(objectClass,"sPcName","Ljava/lang/String;");
  jfieldID srcAddr = (env)->GetFieldID(objectClass,"dwSrcAddr","Ljava/lang/String;");
  jfieldID dstAddr = (env)->GetFieldID(objectClass,"dwDstAddr","Ljava/lang/String;");
  jfieldID ID = (env)->GetFieldID(objectClass,"sID","Ljava/lang/String;");
  jfieldID styles = (env)->GetFieldID(objectClass,"style","Ljava/lang/String;");
  jfieldID content = (env)->GetFieldID(objectClass,"sContent","Ljava/lang/String;");
  jfieldID address = (env)->GetFieldID(objectClass,"sAddress","Ljava/lang/String;");


   int account=0;
   char * pcappoint;
   char * pcontent;
   while(file.Read(&log,LogSize)==(DWORD)LogSize)
   {
       //1
    pcappoint=new char();
   //  str = (*env)->NewStringUTF( env, sa[i] );
    CString capstr=log.tmCapture.Format("%Y-%m-%d %H:%M:%S");
    //CString capstr=new CString("abc");
    pcappoint=capstr.GetBuffer(capstr.GetLength());
    jstring jcap = WindowsTojstring(env,pcappoint);
    (env)->SetObjectField(_obj,capTrue,jcap );
    
    //2
    char * puser=new char();
    CString cuser=log.sUser;
    puser=cuser.GetBuffer(cuser.GetLength());
    jstring juser = WindowsTojstring(env,puser);
    juser = WindowsTojstring(env,puser);
    (env)->SetObjectField(_obj,user,juser );
    //3
    char * psrcMac=new char();
    CString csrcMac=log.sSrcMac;
     psrcMac=csrcMac.GetBuffer(csrcMac.GetLength());
    jstring jsrcMac = WindowsTojstring(env,psrcMac);
    (env)->SetObjectField(_obj,srcMac,jsrcMac );
    //4
    char * ppcName=new char();
    CString cpcName=log.sPcName;
    ppcName=cpcName.GetBuffer(cpcName.GetLength());
    jstring jcpcName = WindowsTojstring(env,ppcName);
    (env)->SetObjectField(_obj,pcName,jcpcName );
    //5
    char * psrcAddr=new char();
    CString csrcAddr=GetIPStr(log.dwSrcAddr);
    psrcAddr=csrcAddr.GetBuffer(csrcAddr.GetLength());
    jstring jsrcAddr = WindowsTojstring(env,psrcAddr);
    (env)->SetObjectField(_obj,srcAddr,jsrcAddr );
    //6
    char * pDstAddr=new char();
    CString cDstAddr=GetIPStr(log.dwDstAddr);
    pDstAddr=cDstAddr.GetBuffer(cDstAddr.GetLength());
    jstring jcDstAddr = WindowsTojstring(env,pDstAddr);
    (env)->SetObjectField(_obj,dstAddr,jcDstAddr );
    //7
    char * pstyle=new char();
    CString cstyle=log.style;
    pstyle=cstyle.GetBuffer(cstyle.GetLength());
    jstring jstyles = WindowsTojstring(env,pstyle);
    (env)->SetObjectField(_obj,styles,jstyles );
    //8
    char * psID=new char();
    CString csID=log.sID;
    psID=csID.GetBuffer(csID.GetLength());
    jstring jsID= WindowsTojstring(env,psID);
    (env)->SetObjectField(_obj,ID,jsID );

    //9
    pcontent=new char();
    CString ccontent=log.sContent;
    pcontent=ccontent.GetBuffer(ccontent.GetLength());
    ccontent.ReleaseBuffer();
    jstring jcontent=WindowsTojstring(env,pcontent);
   // jstring jcontent=(env)->NewStringUTF(env, pcontent);
    (env)->SetObjectField(_obj,content,jcontent );
    //10
    char * pAddress=new char();
    CString cAddress= log.sAddress;
    pAddress=cAddress.GetBuffer(cAddress.GetLength());
    jstring jAddress= WindowsTojstring(env,pAddress);
    (env)->SetObjectField(_obj,address,jAddress );
    
    (env)->SetObjectArrayElement(args, account, _obj);
    account++;
   }
   file.Close();
 }

 //jstring sResult;
 //sResult=env->NewStringUTF(str);

 return args;

这个返回的是有对数组。不过这种方法现在还是有点问题,应该是指针地址的问题,最后面的对象会吧前面的对象覆盖,造成数据重复。所以现在目前是采用第一种方案。哪位大哥如果能看出第二种方案的问题,请跟我联系,QQdanke 56355337

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值