这几天公司在搞一个与第三方的软件结合,公司让我去做。由于原来对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