客户提供一台读卡器、sdtapi.dll、WltRS.dll,以及相应的头文件,我是通过java的jni与所写c++代码进行交互,但是java这边接收到的身份证基本信息一直是乱码。先说明c++向java传其他中文不会出现乱码,是在c++读出的身份证信息就是乱码。c++的代码如下:
#include "windows.h"
#include "CardReader.h"
#include "sdtapi.h"
#include  "String.h"
#include "WltRS.h"
JNIEXPORT jbyteArray JNICALL Java_CardReader_getMessage(JNIEnv * env, jobject jobj){
    
char*   szStr="mei zhao dao xin xi";
char cInput;
int iRet; //返回码
int iPort; //端口号
int iIfOpen=0; //是否需要打开串口
  unsigned char pucIIN[8];
  unsigned char pucSN[8];
unsigned char pucCHMsg[512]; //文字信息
unsigned char pucPHMsg[1024]; //照片信息
unsigned char pucFPMsg[1024]; //指纹信息 
  unsigned int uiCHMsgLen,uiPHMsgLen;  memset(pucCHMsg,0,sizeof(pucCHMsg));
   int   length;
    jbyteArray   RtnArr   =   NULL; 
jsize arrsize;
    
if(iIfOpen==0){

for (iPort = 1001; iPort <= 1016; iPort++)
        {
            iRet=SDT_OpenPort(iPort);
printf("SDT_OpenPort usb error, error code is: %02x\n", iRet);
printf("SDT_OpenPort usb error, error code is: %02d\n", iPort);
if(iRet==0x90) break;
}


if(iRet!=0x90)
{
  
  printf("SDT_OpenPort error, error code is: %02x\n", iRet);
  SDT_ClosePort(iPort);
  szStr="SDT_OpenPort error";
  printf(szStr);
          length   =   strlen(szStr);   
          arrsize =(jsize)length; 
  
   RtnArr=env->NewByteArray(arrsize); 
          env->SetByteArrayRegion(RtnArr, 0,length, (jbyte*)szStr);
    
        return   RtnArr;
    
}
    
   iRet=SDT_StartFindIDCard(iPort,pucIIN, iIfOpen);
   printf("SDT_StartFindIDCard error, error code is: %02x\n", iRet);
       if (iRet != 0x9f)
        {
               iRet=SDT_StartFindIDCard(iPort,pucIIN, iIfOpen);  //再找卡
                if (iRet != 0x9f)
                {                                   
                    iRet = SDT_ClosePort(iPort);
                    printf("SDT_StartFindIDCard error, error code is: %02x\n", iRet);
                    szStr="SDT_StartFindIDCard error";
          length = strlen(szStr);   
                    arrsize =(jsize)length; 
  
                 RtnArr=env->NewByteArray(arrsize); 
                     env->SetByteArrayRegion(RtnArr, 0,length, (jbyte*)szStr);
    
                     return   RtnArr;
                }
       }
    
   iRet=SDT_SelectIDCard (iPort,pucSN, iIfOpen);
   printf("SDT_SelectIDCard error, error code is: %02x\n", iRet);
            if (iRet != 0x90)
            {
               iRet=SDT_SelectIDCard (iPort,pucSN, iIfOpen); //再选卡
                if (iRet != 0x90)
                {                                   
                    iRet = SDT_ClosePort(iPort);
                    printf("SDT_SelectIDCard error, error code is: %02x\n", iRet);
                    szStr="SDT_SelectIDCard error";
          length   =   strlen(szStr);   
                    arrsize =(jsize)length; 
  
                 RtnArr=env->NewByteArray(arrsize); 
                     env->SetByteArrayRegion(RtnArr, 0,length, (jbyte*)szStr);
    
                     return   RtnArr;
                }
            }
      
 
iRet=SDT_ReadBaseMsg(iPort,pucCHMsg,&uiCHMsgLen, pucPHMsg,&uiPHMsgLen, iIfOpen);
printf("SDT_ReadBaseMsg  error, error code is: %02x\n", iRet);

if(iRet!=0x90)
{
printf("SDT_ReadBaseMsg  error, error code is: %02x\n", iRet);
    if(iIfOpen==0)
  SDT_ClosePort(iPort);
printf("ssaaaasasasaas\n");
 szStr="SDT_ReadBaseMsg error";
 length   =   strlen(szStr);   
         arrsize =(jsize)length;
 RtnArr=env->NewByteArray(arrsize); 
 printf("123345453\n");
         env->SetByteArrayRegion(RtnArr, 0,length, (jbyte*)szStr);
         printf("12sssssssss33454534ssaaaasasasaas");
         return   RtnArr;
}
printf("SDT_ReadBaseMsg OK\n");
if(iIfOpen==0)
SDT_ClosePort(iPort);  RtnArr=env->NewByteArray(uiCHMsgLen); 
printf("pucCHMsg=%s\n",pucCHMsg);
  env->SetByteArrayRegion(RtnArr, 0,uiCHMsgLen, (jbyte*)pucCHMsg);
    
return   RtnArr;
    } length   =   strlen(szStr);   
  arrsize =(jsize)length; 
  RtnArr=env->NewByteArray(arrsize); 
  env->SetByteArrayRegion(RtnArr, 0,length, (jbyte*)szStr);
    
  return   RtnArr;}

解决方案 »

  1.   

    那spiniper你估计身份证的基本信息是用什么编码存储的?
      

  2.   

    学习,我也想用java开发一个,lz用的嵌入式么。
      

  3.   

    唉,现在又有一个问题,要把这个程序移植到linux上,但是客户提供的是两个dll文件,在linux是用不了的,linux动态链接库是用so文件
      

  4.   

    回guoqiangone:我用的不是嵌入式,呵呵,我是开发保险录单时候要用到读卡器。 
      

  5.   

    Linux用不了是否考慮用web service呢?Linux好你像裝了一個什么之後可以和window一樣用。但不記得那個名了。
      

  6.   

    回TomyGuan:老大,好好想一想是要装什么?万分感谢
      

  7.   

    是Wine吧。一個適配層。
    Wine軟件包模擬Windows環境
      

  8.   

    http://linux.e800.com.cn/articles/2008/425/1209064282509769714_1.html這里用來安裝CS
      

  9.   

     基本信息处理
    因为二代身份证里编码为GB13000,在java处理中存在问题,总体处理思想为先把16进制字节高地位互换,然后用UTF-16BE转换成中文字符代码如下
    public static String hexByes2String(byte[] bytes,String charsetName){ 
    if("".equals(charsetName)) charsetName="UTF-16BE";
            try {
    return new String(bytes,charsetName);
    } catch (UnsupportedEncodingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    return "";
    }
    public static byte[] hexBytesH2L(byte[] bytes)
    {
    byte tmp = 0;
    for(int i=0;i<bytes.length;i++){

    if(i%2==0) {
    tmp=bytes[i];
    bytes[i]=bytes[i+1];

    }
    else bytes[i]=tmp;

    }
    return bytes;
    }
    调用:hexByes2String(XSocketUtils.hexBytesH2L(hexBytes),"UTF-16BE")
     图片信息处理(用到jna.jar包)
    图片信息处理必须调用第三方提供dll,GETINFO.DLL,过程是先在java中保存16进制字节为一个wlt文件在用GETINFO.DLL中的getBMP函数,生成bmp图片,在从bmp提取图片字节,函数如下(直接调用getPictureBytes即可)import com.sun.jna.Library;
    import com.sun.jna.Native;public class GetSFZPic {
    public interface CLibrary extends Library {
          CLibrary wltToBmp = (CLibrary)  Native.loadLibrary("GETINFO",CLibrary.class);  
          void GetBmp(String wltfile,int a);
        }
    private  static void generatePictureBmp(byte[] picbytes,String idcard){
    try {
       String wltfile=System.getProperty( "user.dir")+"\\shxxcjxtzp.wlt";
       if(null!=picbytes){
     DataOutputStream out=new DataOutputStream(   
                               new BufferedOutputStream(   
                               new FileOutputStream(wltfile))); 
         out.write(picbytes);
         out.close();
    }
       CLibrary.wltToBmp.GetBmp(wltfile, 1);
    } catch (IOException e) {
       e.printStackTrace();
        } }
    public synchronized static byte[] getPictureBytes(byte[]picbytes,String idcard) { String filename=System.getProperty( "user.dir")+"\\shxxcjxtzp.bmp";
    generatePictureBmp(picbytes,idcard);
        File file =new File(filename);
        if(filename==null || filename.equals(""))     {
          throw new NullPointerException("无效的文件路径");
        }
        long len = file.length();
        byte[] bytes = new byte[(int)len];
        System.out.println(filename+"--------"+len);
        BufferedInputStream bufferedInputStream;
    try {
    bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
        int r = bufferedInputStream.read( bytes );
        if (r != len)
          throw new IOException("读取文件不正确");
        bufferedInputStream.close();
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
        return bytes; }
    }