树莓派在身份证件核验领域应用

树莓派结合身份证阅读器的应用

作者:Mr.Kim.Wu 

邮箱:mrkimwu@gmail.com

发布:2013-10-08

关键字:RaspberryPi,Raspi,RPI,树莓派,身份证阅读器,二代证,身份证,居民身份证,RFID,NFC,Debian,linux,创客

 

一、简介

1.1 第二代居民身份证

第二代居民身份证是一种既具有视读,又具有机读两种功能的法定有效证件。证件内记录了公民的身份信息,是不可以替代而且不能非法复制、仿制的证件,具有唯一性。自2004年换发第二代居民身份证工作正式开展以来,全国二代证的换发量已接近12亿张,基本上人手一张。

第二代居民身份证是由多层聚酯材料复合而成的单页卡式证件,采用非接触式IC卡技术制作,具备视读和机读两种功能。证件尺寸设计长85.6毫米,宽54毫米,厚1.0毫米。证件正面有姓名、性别、民族、出生日期、常住户口所在地住址、公民身份号码和本人相片7个登记项目,印有彩色花纹。证件背面有签发机关和有效期限2个登记项目,印有国徽图案、证件名称、写意长城图案和彩色花纹。

第二代居民身份证有六大变化:融入RFID技术、防伪性能提高、办证时间缩短、存储信息增多、有效期重新确定、发放范围扩大等。

 

1.2 身份证阅读器

居民身份证阅读器接口技术规范符合GA 467-2004国家标准,新制定的标准里增加了指纹内容。

二代身份证读卡器是一种能判断身份证是否伪造的设备,像验钞机一样,能对身份证真伪进行有效识别,二代证内含有RFID芯片,通过二代身份证读卡器,身份证芯片内所存储信息,包括姓名,地址,照片等信息将一一显示,二代证芯片采用智能卡技术,其芯片无法复制,高度防伪,配合二代身份证读卡器,假身份证将无处藏身。可读取、查询第二代居民身份证全部信息,可验证第二代居民身份证真伪。

具有以下特点:

● 通用性强:支持WIN98/2000/XP/NT/WINCE/LINUX等多种操作系统。

● 开放性好:提供SDK供系统集成商进行二次开发。

● 功能强大:可外接标准键盘、鼠标、显示器,提供RS-232C、USB计算机接口。

● 扩展灵活:可加装指纹采集器,现场比对持证人的指纹,进行“人证同一性”认定。也可以外接数码采集设备,采集个人相片、文字等信息,作信息采集设备使用。

● 操作简便:开机即进入阅读界面,阅读软件自动找卡和阅读。

 

1.3 树莓派 Raspberry Pi

树莓派(英语:RaspberryPi),是一款基于Linux系统的只有一张信用卡大小的单板机计算机。它由英国的树莓派基金会所开发,目的是以低价硬件及自由软件刺激在学校的基本的电脑科学教育。

相关介绍请参考维基:

http://zh.wikipedia.org/wiki/%E6%A0%91%E8%8E%93%E6%B4%BE


树莓派板载2个USB接口,以及丰富的外设端口,方便与各类外设通讯。

本文实现了树莓派与身份证阅读器的连接,阅读显示身份证芯片内容。

二、准备工作

2.1设备清单:

l       树莓派+ SD卡Class 4/ Class 10 8G

l       USB转RS232串口线:ProlificUSB-to-Serial Bridg Y-105 (PL2303HX)

l       RS232接口身份证阅读器

l       TP-Link无线网络路由器

 

 

2.2软件

l       字符终端:SecureCRT软件

l       文件传输: FileZilla软件 SFTP(SSH2)传输协议

l       远程桌面:

u     Windows:VNC Viewer或UltraVNC-Viewer

u     Android:AndroidVNC

三、实现步骤

3.1连接方式

本文使用树莓派板载USB口,通过USB转换线转成UART RS232串口与身份证9针RS232串口相连: USB<->RS232

USB 驱动:免驱动安装

在树莓派USB口插上阅读器之后查看USB<-> RS232设备:

ls -l /dev/ttyUSB0

如果直接使用树莓派板载GPIOTTL串口ttyAMA0可参考下面2个网址:

http://www.savagehomeautomation.com/projects/raspberry-pi-rs232-serial-interface-options-revisit.html

http://www.irrational.net/2012/04/19/using-the-raspberry-pis-serial-port/

注意:树莓派板载TTL串口不可直接与身份证阅读器串口相连,电平不匹配容易损坏树莓派板载TTL串口。

 

3.2开发工具链

开发语言:

G++开发底层通讯库。

界面开发语言:本文使用GTK+(GIMP Toolkit)作开发界面

界面设计工具:Glade

其他可选语言:PythonJava、QT、LazarusPascal

 

3.3软件开发

本文采用调用串口设备/dev/ttyUSB0的方法。

另外一种是直接调用身份证阅读器的USB IO管道 Pipe驱动设备,

这种方法需要开发专用USB驱动,需熟悉USB协议,比较麻烦。

 

首先保证串口转换线能用。

短接RS232串口的2,3脚。

编写串口测试程序一:

参考:https://sites.google.com/site/semilleroadt/raspberry-pi-tutorials/gpio

去这个网站下载并安装最新的Pyserial库 

http://sourceforge.net/projects/pyserial/files/pyserial/

//Python测试程序 testserial.py 

  1. import serial  
  2. ser =serial.Serial("/dev/ttyUSB0",115200,timeout=1)  
  3. ser.write("UARTthe Font")  
  4. read =ser.read(13)  
  5. print read  
  6. ser.close()  
import serial
ser =serial.Serial("/dev/ttyUSB0",115200,timeout=1)
ser.write("UARTthe Font")
read =ser.read(13)
print read
ser.close()

运行Python testserial.py 

可以在终端看到输出一串字符UARTthe Font,如果不短接2,3脚将会在超时1秒后程序自动退出,直接换行输出空白。

串口测试方法二:

http://raspberrypi.stackexchange.com/questions/4801/usart-resending-problem-via-console
    在SSH字符终端输入

  1. sudo stty 115200-F /dev/ttyUSB0 -echo -onlcr  
  2. cat /dev/ttyUSB0  
sudo stty 115200-F /dev/ttyUSB0 -echo -onlcr
cat /dev/ttyUSB0

在VNC远程桌面终端输入

  1. echo hello>> /dev/ttyUSB0  
echo hello>> /dev/ttyUSB0

 

授权许可:

身份证阅读器通讯库代码ABCVUtility.cpp、ABCVlib.cpp采用开源GPL授权许可协议,照片图像解码需采用公安专用授权许可协议。详请联系作者。

 

阅读器串口通讯协议(具体请参考标准GA 467-2004):

树莓派与身份阅读器采用命令/应答方式进行数据交换。

数据通讯帧格式:

命令数据输入帧格式

帧头

长度H

长度L

命令码

命令参数

数据内容

校验和

应答数据输出帧格式

帧头

长度H

长度L

SW1

状态

SW2

状态SW3

数据内容

校验和

 

身份证芯片存储编码格式:

文字:256字节Unicode 编码,可转换成GBK码。

照片:1024字节图像压缩编码。

 

开始敲代码:


///

//ABCVlib.cpp代码

  1. #include<stdio.h>  
  2. #include<fcntl.h>  
  3. #include<time.h>  
  4. #include<stdlib.h>  
  5. #include<string.h>  
  6. #include<unistd.h>   
  7. #include"ABCVlib.h"  
  8. #include"ABCVUtility.h"  
  9.    
  10.    
  11. /*帧头*/  
  12. #define Preamble00xDD  
  13. #define Preamble10xDD  
  14. #define Preamble20xDD  
  15. #define Preamble30xDD  
  16. #define Preamble40xDD  
  17.    
  18.    
  19.    
  20. /*返回错误代码*/  
  21. #define         RD_OK             0     //操作成功  
  22. #define   OPENPORT_ERR      -1    //打开端口失败  
  23. #define   TIMEOUT_ERR       -2    //超时  
  24. #define         RD_CARD_ERR      -3    //无卡或读卡失败  
  25.    
  26. #define   CHECKSUM_ERR      -4    //校验和错  
  27. #define   FILE_ERR          -5    //读卡结果文件打开出错  
  28.    
  29. /*机器命令码*/  
  30. const unsignedchar CMD_SAM_READALLMSG[2]={0x00, 0x00};  
  31.    
  32. /*机器响应命令*/  
  33. #define SW1      inBuffer[7]  
  34. #define SW2      inBuffer[8]  
  35. #define SW3      inBuffer[9]  
  36. #define SAMSTATE     inBuffer[9]  
  37. #defineRD_SAM_OK    0x90          //操作成功  
  38.    
  39. struct defMsg{  
  40.   unsigned char name[30];  
  41.   unsigned char sex[2];  
  42.   unsigned char nation[4];  
  43.   unsigned char bY[8],bM[4],bD[4];  
  44.   unsigned char address[70];  
  45.   unsigned char id[36];  
  46.   unsigned char depart[30];  
  47.   unsigned char tsY[8],tsM[4],tsD[4];  
  48.   unsigned char tpY[8],tpM[4],tpD[4];  
  49. };  
  50.    
  51. #define MSG((struct defMsg *)&inBufferTMP[0])  
  52.    
  53.    
  54. unsigned charinBuffer[2500],inBufferTMP[2500], outBuffer[50];  
  55. unsigned longnBytesWrite=0;  
  56. int CheckSum=0;  
  57. char TMP[512];  
  58. charchNation[100];  
  59.    
  60. /******************************************************************************* 
  61. 函数名:     *  abcv_SetPreamble      添加数据帧头 
  62. 输入参数:   *   无 
  63. 输出参数:   *   无 
  64. *******************************************************************************/  
  65. voidabcv_SetPreamble()  
  66. {  
  67.     outBuffer[0]=Preamble0;   
  68.     outBuffer[1]=Preamble1;  outBuffer[2]=Preamble2;  
  69.     outBuffer[3]=Preamble3;  outBuffer[4]=Preamble4;  CheckSum=0;  
  70.     nBytesWrite=0x05;     
  71. }  
  72.    
  73. /******************************************************************************* 
  74. 函数名:     *  abcv_CheckControlCode           加入待发数据 
  75. 输入参数:   *  unsigned char value        加入的数据 
  76. 输出参数:   *   无 
  77. *******************************************************************************/  
  78. voidabcv_CheckControlCode(unsigned char value)  
  79. {  
  80.     CheckSum ^= value;  
  81.     outBuffer[nBytesWrite]=value;     
  82.     nBytesWrite++;   
  83. }  
  84.    
  85.    
  86. int abcv_ReadMsg(intterm, int port, int timeout, unsigned char *pucCHMsg, int *piCHMsgLen, unsignedchar *pucPHMsg, int *piPHMsgLen)  
  87. {  
  88.    int Rtn=0;   int i=0;   int nBytes=0;  
  89.    FILE *f;  
  90.    //unsigned char TMP[512];  
  91.    //unsigned char chNation[100];  
  92.     
  93.        if(abcv_openPort(term,port)== -1) return (OPENPORT_ERR);  
  94.         
  95.    memset(outBuffer,'\0',50);  
  96.    //memset(inBuffer,'\0',2500);    
  97.    abcv_SetPreamble();  
  98.    abcv_CheckControlCode(0x00);   
  99.    abcv_CheckControlCode(0x03);   
  100.    abcv_CheckControlCode(CMD_SAM_READALLMSG[0]);   
  101.    abcv_CheckControlCode(CMD_SAM_READALLMSG[1]);   
  102.    abcv_CheckControlCode(CheckSum);  
  103.     
  104.    abcv_write_n(term, outBuffer, nBytesWrite);  
  105.    //接收帧头    
  106.        Rtn= abcv_read_n(term, inBuffer, 7, timeout);          
  107.        if(Rtn<7)  
  108.        {  
  109.           abcv_closePort(term);  
  110.            return(TIMEOUT_ERR);      //接收超时    
  111.    }           
  112.    if(inBuffer[0]!=Preamble0 ||inBuffer[1]!=Preamble1 ||  
  113.           inBuffer[2]!=Preamble2|| inBuffer[3]!=Preamble3 ||  
  114.           inBuffer[4]!=Preamble4)  
  115.         {  
  116.           abcv_closePort(term);  
  117.           return(TIMEOUT_ERR);      //接收超时    
  118.    }   
  119.        nBytes=inBuffer[5]*256+inBuffer[6];//计算数据长度  
  120.            
  121.    //接收指定长度的数据  
  122.    Rtn = abcv_read_n(term, &inBuffer[7],nBytes, timeout);             
  123.        abcv_closePort(term);     
  124.         
  125.        if(Rtn<nBytes)  
  126.        {  
  127.           abcv_closePort(term);  
  128.           return(TIMEOUT_ERR);      //接收超时    
  129.    }   
  130.    CheckSum=0;  
  131.    for (i=5;i<nBytes+6;i++)  
  132.         CheckSum^=inBuffer[i];  
  133.        if(CheckSum!=inBuffer[nBytes+6])  
  134.        {  
  135.           abcv_closePort(term);  
  136.           return(CHECKSUM_ERR);      //校验和错    
  137.    }   
  138.    //返回状态码   
  139.       if(SW1==0x00 && SW2==0x00 && SW3==RD_SAM_OK)  
  140.       {           
  141.           *piCHMsgLen=256;      
  142.           *piPHMsgLen=1024;            
  143.           memcpy(pucCHMsg,&inBuffer[14],256);  
  144.           memcpy(pucPHMsg,&inBuffer[270],1024);  
  145.           memcpy(inBufferTMP,&inBuffer[14],256);  
  146.           return (RD_OK);              
  147.       }  
  148.       else   
  149.    {           
  150.           return(RD_CARD_ERR);  
  151.        }  
  152.         return (RD_CARD_ERR);       
  153.           
  154. }  
  155.    
  156.    
  157. intabcv_ReadIDCard(int term, int port, int timeout,  
  158.           unsigned char *pucCHMsg, int*piCHMsgLen, unsigned char *pucPHMsg, int *piPHMsgLen)  
  159.            
  160. {  
  161.    int RTN;  
  162.    FILE *f;  
  163.    char *wzfile="./wz.txt";  
  164.    char *wltfile="./xp.wlt";  
  165.   char*bmpfile="./xp.bmp";       
  166.    
  167.        unsignedchar CHMsg[512],PHMsg[1024];  
  168.        unsignedint CHMsgLen,PHMsgLen;  
  169.    
  170.        RTN=abcv_ReadMsg(term,port, timeout, CHMsg,&CHMsgLen,PHMsg,&PHMsgLen);     
  171.        if(RTN!=RD_OK) return(RTN);  
  172.        
  173.       *piCHMsgLen=256;      
  174.       *piPHMsgLen=1024;  
  175.       memcpy(pucCHMsg,CHMsg,256);  
  176.       memcpy(pucPHMsg,PHMsg,1024);        
  177.      
  178.         
  179.        f=fopen(wzfile,"wb");  
  180.        if(f==NULL) return(FILE_ERR);             
  181.    if (fwrite(CHMsg,CHMsgLen,1,f)!=1){  
  182.        fclose(f);  
  183.        return(FILE_ERR);  
  184.        }             
  185.        fclose(f);  
  186.         
  187.              
  188.        f=fopen(wltfile,"wb");  
  189.    if (f==NULL) return(FILE_ERR);   
  190.    if (fwrite(PHMsg,PHMsgLen,1,f)!=1){     
  191.        fclose(f);  
  192.        return(FILE_ERR);  
  193.    }  
  194.    fclose(f);           
  195.     
  196.    //  
  197.    
  198.     return(RD_OK);     
  199. }  
  200.    
  201.    
  202.    
  203. intabcv_getName(char * szName)  
  204. {  
  205.   memset(TMP,'\0',512);  
  206.   abcv_strUnicode2GB(MSG->name,TMP,30);    
  207.   sprintf( szName,"%s",TMP);       //       姓名:    
  208.   return (0);  
  209. }  
  210.    
  211. intabcv_getSex(char * szSex)  
  212. {  
  213.   memset(TMP,'\0',512);         
  214.   abcv_strUnicode2GB(MSG->sex,TMP,2);  
  215.                                 
  216.   if ( memcmp(TMP,"1",1)==0 )  
  217.    sprintf( szSex,"男");     //       性别:  
  218.   else  
  219.    sprintf( szSex,"女");  
  220.         
  221.   return (0);  
  222. }  
  223. //… …<span style="font-family:Arial,Helvetica,sans-serif; background-color:rgb(255,255,255)"> </span>  
#include<stdio.h>
#include<fcntl.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h> 
#include"ABCVlib.h"
#include"ABCVUtility.h"
 
 
/*帧头*/
#define Preamble00xDD
#define Preamble10xDD
#define Preamble20xDD
#define Preamble30xDD
#define Preamble40xDD
 
 
 
/*返回错误代码*/
#define         RD_OK             0     //操作成功
#define   OPENPORT_ERR      -1    //打开端口失败
#define   TIMEOUT_ERR       -2    //超时
#define         RD_CARD_ERR      -3    //无卡或读卡失败
 
#define   CHECKSUM_ERR      -4    //校验和错
#define   FILE_ERR          -5    //读卡结果文件打开出错
 
/*机器命令码*/
const unsignedchar CMD_SAM_READALLMSG[2]={0x00, 0x00};
 
/*机器响应命令*/
#define SW1      inBuffer[7]
#define SW2      inBuffer[8]
#define SW3      inBuffer[9]
#define SAMSTATE     inBuffer[9]
#defineRD_SAM_OK    0x90          //操作成功
 
struct defMsg{
  unsigned char name[30];
  unsigned char sex[2];
  unsigned char nation[4];
  unsigned char bY[8],bM[4],bD[4];
  unsigned char address[70];
  unsigned char id[36];
  unsigned char depart[30];
  unsigned char tsY[8],tsM[4],tsD[4];
  unsigned char tpY[8],tpM[4],tpD[4];
};
 
#define MSG((struct defMsg *)&inBufferTMP[0])
 
 
unsigned charinBuffer[2500],inBufferTMP[2500], outBuffer[50];
unsigned longnBytesWrite=0;
int CheckSum=0;
char TMP[512];
charchNation[100];
 
/*******************************************************************************
函数名:     *  abcv_SetPreamble      添加数据帧头
输入参数:   *   无
输出参数:   *   无
*******************************************************************************/
voidabcv_SetPreamble()
{
    outBuffer[0]=Preamble0; 
    outBuffer[1]=Preamble1;  outBuffer[2]=Preamble2;
    outBuffer[3]=Preamble3;  outBuffer[4]=Preamble4;  CheckSum=0;
    nBytesWrite=0x05;   
}
 
/*******************************************************************************
函数名:     *  abcv_CheckControlCode           加入待发数据
输入参数:   *  unsigned char value        加入的数据
输出参数:   *   无
*******************************************************************************/
voidabcv_CheckControlCode(unsigned char value)
{
    CheckSum ^= value;
    outBuffer[nBytesWrite]=value;   
    nBytesWrite++; 
}
 
 
int abcv_ReadMsg(intterm, int port, int timeout, unsigned char *pucCHMsg, int *piCHMsgLen, unsignedchar *pucPHMsg, int *piPHMsgLen)
{
   int Rtn=0;   int i=0;   int nBytes=0;
   FILE *f;
   //unsigned char TMP[512];
   //unsigned char chNation[100];
  
       if(abcv_openPort(term,port)== -1) return (OPENPORT_ERR);
      
   memset(outBuffer,'\0',50);
   //memset(inBuffer,'\0',2500);  
   abcv_SetPreamble();
   abcv_CheckControlCode(0x00); 
   abcv_CheckControlCode(0x03); 
   abcv_CheckControlCode(CMD_SAM_READALLMSG[0]); 
   abcv_CheckControlCode(CMD_SAM_READALLMSG[1]); 
   abcv_CheckControlCode(CheckSum);
  
   abcv_write_n(term, outBuffer, nBytesWrite);
   //接收帧头  
       Rtn= abcv_read_n(term, inBuffer, 7, timeout);        
       if(Rtn<7)
       {
          abcv_closePort(term);
           return(TIMEOUT_ERR);      //接收超时  
   }         
   if(inBuffer[0]!=Preamble0 ||inBuffer[1]!=Preamble1 ||
          inBuffer[2]!=Preamble2|| inBuffer[3]!=Preamble3 ||
          inBuffer[4]!=Preamble4)
        {
          abcv_closePort(term);
          return(TIMEOUT_ERR);      //接收超时  
   } 
       nBytes=inBuffer[5]*256+inBuffer[6];//计算数据长度
         
   //接收指定长度的数据
   Rtn = abcv_read_n(term, &inBuffer[7],nBytes, timeout);           
       abcv_closePort(term);   
      
       if(Rtn<nBytes)
       {
          abcv_closePort(term);
          return(TIMEOUT_ERR);      //接收超时  
   } 
   CheckSum=0;
   for (i=5;i<nBytes+6;i++)
        CheckSum^=inBuffer[i];
       if(CheckSum!=inBuffer[nBytes+6])
       {
          abcv_closePort(term);
          return(CHECKSUM_ERR);      //校验和错  
   } 
   //返回状态码 
      if(SW1==0x00 && SW2==0x00 && SW3==RD_SAM_OK)
      {         
          *piCHMsgLen=256;    
          *piPHMsgLen=1024;          
          memcpy(pucCHMsg,&inBuffer[14],256);
          memcpy(pucPHMsg,&inBuffer[270],1024);
          memcpy(inBufferTMP,&inBuffer[14],256);
          return (RD_OK);            
      }
      else 
   {         
          return(RD_CARD_ERR);
       }
        return (RD_CARD_ERR);     
        
}
 
 
intabcv_ReadIDCard(int term, int port, int timeout,
          unsigned char *pucCHMsg, int*piCHMsgLen, unsigned char *pucPHMsg, int *piPHMsgLen)
         
{
   int RTN;
   FILE *f;
   char *wzfile="./wz.txt";
   char *wltfile="./xp.wlt";
  char*bmpfile="./xp.bmp";     
 
       unsignedchar CHMsg[512],PHMsg[1024];
       unsignedint CHMsgLen,PHMsgLen;
 
       RTN=abcv_ReadMsg(term,port, timeout, CHMsg,&CHMsgLen,PHMsg,&PHMsgLen);   
       if(RTN!=RD_OK) return(RTN);
     
      *piCHMsgLen=256;    
      *piPHMsgLen=1024;
      memcpy(pucCHMsg,CHMsg,256);
      memcpy(pucPHMsg,PHMsg,1024);      
   
      
       f=fopen(wzfile,"wb");
       if(f==NULL) return(FILE_ERR);           
   if (fwrite(CHMsg,CHMsgLen,1,f)!=1){
       fclose(f);
       return(FILE_ERR);
       }           
       fclose(f);
      
           
       f=fopen(wltfile,"wb");
   if (f==NULL) return(FILE_ERR); 
   if (fwrite(PHMsg,PHMsgLen,1,f)!=1){   
       fclose(f);
       return(FILE_ERR);
   }
   fclose(f);         
  
   //
 
    return(RD_OK);   
}
 
 
 
intabcv_getName(char * szName)
{
  memset(TMP,'\0',512);
  abcv_strUnicode2GB(MSG->name,TMP,30);  
  sprintf( szName,"%s",TMP);       //       姓名:  
  return (0);
}
 
intabcv_getSex(char * szSex)
{
  memset(TMP,'\0',512);       
  abcv_strUnicode2GB(MSG->sex,TMP,2);
                              
  if ( memcmp(TMP,"1",1)==0 )
   sprintf( szSex,"男");     //       性别:
  else
   sprintf( szSex,"女");
      
  return (0);
}
//… …<span style="font-family:Arial,Helvetica,sans-serif; background-color:rgb(255,255,255)"> </span>

/

以上cpp 的Makefile:

  1. #  
  2. # libABCVLib.soMakefile  
  3. #  
  4.    
  5. ARM_PREFIX=arm-linux-gnueabihf-  
  6. CC   = $(ARM_PREFIX)g++  
  7. LD      := ld  
  8. CFLAGS  := -fpermissive  
  9. LDFLAGS := -shared-fpic  
  10. SOURCE  := $(wildcard *.cpp)  
  11. OBJS    := $(patsubst %.cpp,%.o,$(SOURCE))  
  12. TARGET_LIB := libABCVLib.so  
  13.    
  14. all:$(OBJS)  
  15.        echo $(OBJS)  
  16.        $(LD) $(LDFLAGS) -o $(TARGET_LIB) $(OBJS)  
  17.    
  18. %.o:%.cpp  
  19.        @echo Compiling $< ...  
  20.        $(CC) -c $(CFLAGS)  $< -o $*.o  
  21.           
  22. .PHONY: clean  
  23.    
  24. clean:  
  25.        rm *.so *.o –rf  
#
# libABCVLib.soMakefile
#
 
ARM_PREFIX=arm-linux-gnueabihf-
CC   = $(ARM_PREFIX)g++
LD      := ld
CFLAGS  := -fpermissive
LDFLAGS := -shared-fpic
SOURCE  := $(wildcard *.cpp)
OBJS    := $(patsubst %.cpp,%.o,$(SOURCE))
TARGET_LIB := libABCVLib.so
 
all:$(OBJS)
       echo $(OBJS)
       $(LD) $(LDFLAGS) -o $(TARGET_LIB) $(OBJS)
 
%.o:%.cpp
       @echo Compiling $< ...
       $(CC) -c $(CFLAGS)  $< -o $*.o
        
.PHONY: clean
 
clean:
       rm *.so *.o –rf

 

 

so编译环境设置:

生成的共享库libABCVLib.so在非标准路经,ld.so 怎么找到它呢?

目前,Linux 通用的做法是将非标准路经加入 /etc/ld.so.conf,然后运行 ldconfig 生成 /etc/ld.so.cache。ld.so加载共享库的时候,会从ld.so.cache 查找。

或者在/etc/ld.so.conf.d/目录下新建一个共享库名字对应的conf文件:libABCVLib.conf,文件内容为你的工作目录,本文为/home/pi/kim/gtk30

 

图形界面: 采用GTK+图形工具包调用libABCVLib.so 动态库显示身份证文字和照片。

图形界面开发参考网址:http://hertaville.com/2012/09/28/development-environment-raspberry-pi-cross-compiler/http://hertaville.com/2013/07/19/cross-compiling-gtk-applications-for-the-raspberry-pi/

  1. //gtktest.c  
  2. #include<gtk/gtk.h>  
  3. #include<stdio.h>  
  4. #include<stdlib.h>  
  5. #include<string.h>  
  6. #include<time.h>  
  7. #include<termio.h>  
  8. #include<unistd.h>  
  9. #include<errno.h>  
  10. #include<iconv.h>  
  11. #include<locale.h>  
  12. #include<ABCVlib.h>   
  13.    
  14. #defineTERM_TYPE       1                //终端类型 默认1  
  15. #defineTERM_PORT       1               //阅读机具所接的串口号  
  16.                                         //1:主机串口一  
  17. #defineTIMEOUT         4               //读卡超时4秒返回  
  18. #define BUFLEN 255   
  19.    
  20.   GtkWidget *window;  
  21.   GtkWidget *frame;   
  22.   GtkWidget *label;  
  23.   GtkWidget *plus;  
  24.   GtkWidget *minus;  
  25.    
  26.   GtkWidget *fixed1;  
  27.   GtkWidget *entrName;  
  28.   GtkWidget *entrSex;  
  29.   GtkWidget *label1;  
  30.   GtkWidget *entrNation;  
  31.   GtkWidget *entrBirthday;  
  32.   GtkWidget *entrAddr;  
  33.   GtkWidget *entrID;  
  34.   GtkWidget *entrDep;  
  35.   GtkWidget *entrValid;  
  36.   GtkWidget *label7;  
  37.   GtkWidget *label9;  
  38.   GtkWidget *hseparator1;  
  39.   GtkWidget *label2;  
  40.   GtkWidget *bt_close;  
  41.   GtkWidget *button1;  
  42.   GtkWidget *label3;  
  43.   GtkWidget *label6;  
  44.   GtkWidget *label5;  
  45.   GtkWidget *label4;  
  46.   GtkWidget *image;  
  47.    
  48. //代码转换:从一种编码转为另一种编码  
  49. int code_convert(char*from_charset,char *to_charset,char *inbuf,int inlen,char *outbuf,int outlen)  
  50. {  
  51.    iconv_t cd;  
  52.    int rc;  
  53.    char **pin = &inbuf;  
  54.    char **pout = &outbuf;  
  55.    
  56.    cd = iconv_open(to_charset,from_charset);  
  57.    if (cd==0) return -1;  
  58.    memset(outbuf,0,outlen);  
  59.    if (iconv(cd,pin,&inlen,pout,&outlen)==-1)return -1;  
  60.    iconv_close(cd);  
  61.    return 0;  
  62. }  
  63. //UNICODE码utf-8转为GB码  
  64. int u2g(char *inbuf,int inlen,char *outbuf,intoutlen)  
  65. {  
  66.    returncode_convert("utf-8","gb2312",inbuf,inlen,outbuf,outlen);  
  67. }  
  68. //GB码转为UNICODE码utf-8  
  69. int g2u(char*inbuf,size_t inlen,char *outbuf,size_t outlen)  
  70. {  
  71.    returncode_convert("gb2312","utf-8",inbuf,inlen,outbuf,outlen);  
  72. }  
  73.    
  74. voidon_bt_close_clicked(GtkButton *button,gpointer user_data)  
  75. {  
  76.    gtk_main_quit();  
  77. }  
  78.    
  79. voidon_bt_ok_clicked (GtkButton *button,gpointer user_data)  
  80. {  
  81.    
  82.   inti,Len,nRet,zpLen;     
  83.    unsigned char Buff[500];  
  84.    char outbuf[BUFLEN];  
  85.    unsigned char zpBuff[1024];  
  86.    char TMP[512];  
  87.    char *wltfile="./xp.wlt";  
  88.   char*bmpfile="./xp.bmp";       
  89.   FILE*f;                             
  90.                                      
  91.  //调用libABCVLib.so 动态库阅读身份证,自动生成文字和照片文件                                   
  92.   nRet =abcv_ReadIDCard (TERM_TYPE, TERM_PORT,TIMEOUT, Buff, &Len, zpBuff, &zpLen); //libABCVLib.so   
  93.   if (nRet==0)  
  94.    {  
  95.          //显示姓名  
  96.            memset(TMP,'\0',512);     
  97.           memset(outbuf,'\0',BUFLEN);         
  98.           abcv_getName(TMP);           
  99.           if ((i=g2u(TMP,strlen(TMP),outbuf,BUFLEN))==0 )  
  100.           {                  
  101.                  gtk_entry_set_text(GTK_ENTRY(entrName),outbuf);   
  102.           }                                   
  103.            
  104.           //显示性别  
  105.           memset(TMP,'\0',512);                      
  106.           abcv_getSex(TMP);  
  107.                   
  108.           if ((i=g2u(TMP,strlen(TMP),outbuf,BUFLEN))==0 )      
  109.           {                               
  110.               gtk_entry_set_text(GTK_ENTRY(entrSex), outbuf);  
  111.           }  
  112.           //显示民族  
  113.           memset(TMP,'\0',512);            
  114.           abcv_getchNation(TMP);       
  115.           if ((i=g2u(TMP,strlen(TMP),outbuf,BUFLEN))==0 )      
  116.           {                               
  117.               gtk_entry_set_text(GTK_ENTRY(entrNation), outbuf);  
  118.           }  
  119.            
  120.           //显示出生日期        
  121.           memset(TMP,'\0',512);                       
  122.           abcv_getBirth(TMP);          
  123.           if ((i=g2u(TMP,strlen(TMP),outbuf,BUFLEN))==0 )      
  124.           {                               
  125.               gtk_entry_set_text(GTK_ENTRY(entrBirthday), outbuf);  
  126.           }  
  127.            
  128.           //显示户籍地址  
  129.           memset(TMP,'\0',512);               
  130.           abcv_getAddr(TMP);               
  131.           if ((i=g2u(TMP,strlen(TMP),outbuf,BUFLEN))==0 )      
  132.           {                               
  133.               gtk_entry_set_text(GTK_ENTRY(entrAddr), outbuf);  
  134.           }  
  135.          //显示身份证号码  
  136.           memset(TMP,'\0',512);               
  137.           abcv_getIdCode(TMP);      
  138.           if ((i=g2u(TMP,strlen(TMP),outbuf,BUFLEN))==0 )      
  139.           {                               
  140.               gtk_entry_set_text(GTK_ENTRY(entrID), outbuf);  
  141.           }  
  142.           //显示签发机关  
  143.           memset(TMP,'\0',512);                   
  144.           abcv_getIssue(TMP);              
  145.           if ((i=g2u(TMP,strlen(TMP),outbuf,BUFLEN))==0 )      
  146.           {                               
  147.               gtk_entry_set_text(GTK_ENTRY(entrDep), outbuf);  
  148.           }  
  149.           //显示证件有效期  
  150.           memset(TMP,'\0',512);               
  151.           abcv_getValidity(TMP);                     
  152.           if ((i=g2u(TMP,strlen(TMP),outbuf,BUFLEN))==0 )      
  153.           {                               
  154.               gtk_entry_set_text(GTK_ENTRY(entrValid), outbuf);  
  155.           }  
  156.                
  157.           //显示身份证照片  
  158.           image =gtk_image_new_from_file(bmpfile);  
  159.           gtk_widget_set_size_request(image,102, 126);  
  160.           gtk_widget_show (image);       
  161.           gtk_fixed_put (GTK_FIXED (fixed1),image, 438, 160);  
  162.                              
  163.    }  
  164.    else {  
  165.        g_warning ("Error Code: %d", nRet);     
  166.    }  
  167. }  
  168.    
  169.     
  170.    
  171. int main(int argc,char** argv) {    
  172.    
  173.   gtk_init(&argc, &argv);  
  174.    
  175.   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);  
  176.   gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);  
  177.   gtk_window_set_default_size (GTK_WINDOW(window), 580, 400);  
  178.   gtk_window_set_title(GTK_WINDOW(window),"Raspi IDCard2 Reader");   
  179.    
  180.   fixed1 = gtk_fixed_new ();  
  181.   gtk_widget_show (fixed1);  
  182.   gtk_container_add (GTK_CONTAINER (window),fixed1);  
  183.   gtk_widget_set_size_request (fixed1, 286,123);  
  184.    
  185.   entrName = gtk_entry_new ();  
  186.   gtk_widget_show (entrName);  
  187.   gtk_fixed_put (GTK_FIXED (fixed1), entrName,96, 16);  
  188.   gtk_widget_set_size_request (entrName, 158,25);  
  189.    
  190.   entrSex = gtk_entry_new ();  
  191.   gtk_widget_show (entrSex);  
  192.   gtk_fixed_put (GTK_FIXED (fixed1), entrSex,96, 72);  
  193.   gtk_widget_set_size_request (entrSex, 84,25);  
  194.    
  195.   label1 = gtk_label_new("\345\247\223  \345\220\215");  
  196.   gtk_widget_show (label1);  
  197.   gtk_fixed_put (GTK_FIXED (fixed1), label1, 8,23);  
  198.   gtk_widget_set_size_request (label1, 82, 17);  
  199.    
  200.   entrNation = gtk_entry_new ();  
  201.   gtk_widget_show (entrNation);  
  202.   gtk_fixed_put (GTK_FIXED (fixed1),entrNation, 344, 72);  
  203.   gtk_widget_set_size_request (entrNation, 84,25);  
  204.    
  205.   entrBirthday = gtk_entry_new ();  
  206.   gtk_widget_show (entrBirthday);  
  207.   gtk_fixed_put (GTK_FIXED (fixed1),entrBirthday, 96, 112);  
  208.   gtk_widget_set_size_request (entrBirthday,160, 25);  
  209.    
  210.   entrAddr = gtk_entry_new ();  
  211.   gtk_widget_show (entrAddr);  
  212.   gtk_fixed_put (GTK_FIXED (fixed1), entrAddr,96, 160);  
  213.   gtk_widget_set_size_request (entrAddr, 331,25);  
  214.    
  215.   entrID = gtk_entry_new ();  
  216.   gtk_widget_show (entrID);  
  217.   gtk_fixed_put (GTK_FIXED (fixed1), entrID,96, 200);  
  218.   gtk_widget_set_size_request (entrID, 331,25);  
  219.    
  220.   entrDep = gtk_entry_new ();  
  221.   gtk_widget_show (entrDep);  
  222.   gtk_fixed_put (GTK_FIXED (fixed1), entrDep,96, 240);  
  223.   gtk_widget_set_size_request (entrDep, 331,25);  
  224.    
  225.   entrValid = gtk_entry_new ();  
  226.   gtk_widget_show (entrValid);  
  227.   gtk_fixed_put (GTK_FIXED (fixed1), entrValid,96, 280);  
  228.   gtk_widget_set_size_request (entrValid, 331,25);  
  229.    
  230.   label7 = gtk_label_new("\345\217\221\350\257\201\346\234\272\345\205\263");  
  231.   gtk_widget_show (label7);  
  232.   gtk_fixed_put (GTK_FIXED (fixed1), label7,16, 240);  
  233.   gtk_widget_set_size_request (label7, 68, 25);  
  234.    
  235.   label9 = gtk_label_new("\346\234\211\346\225\210\346\234\237\351\231\220");  
  236.   gtk_widget_show (label9);  
  237.   gtk_fixed_put (GTK_FIXED (fixed1), label9,16, 280);  
  238.   gtk_widget_set_size_request (label9, 68, 17);  
  239.    
  240.   hseparator1 = gtk_hseparator_new ();  
  241.   gtk_widget_show (hseparator1);  
  242.   gtk_fixed_put (GTK_FIXED (fixed1),hseparator1, 24, 312);  
  243.   gtk_widget_set_size_request (hseparator1,426, 16);  
  244.    
  245.   label2 = gtk_label_new("\346\200\247  \345\210\253");  
  246.   gtk_widget_show (label2);  
  247.   gtk_fixed_put (GTK_FIXED (fixed1), label2,16, 80);  
  248.   gtk_widget_set_size_request (label2, 64, 17);  
  249.    
  250.   bt_close = gtk_button_new_with_mnemonic("\351\200\200\345\207\272");  
  251.   gtk_widget_show (bt_close);  
  252.   gtk_fixed_put (GTK_FIXED (fixed1), bt_close,296, 336);  
  253.   gtk_widget_set_size_request (bt_close, 53,27);  
  254.    
  255.   button1 = gtk_button_new_with_mnemonic("\350\257\273\345\215\241");  
  256.   gtk_widget_show (button1);  
  257.   gtk_fixed_put (GTK_FIXED (fixed1), button1,152, 336);  
  258.   gtk_widget_set_size_request (button1, 53, 27);  
  259.    
  260.   label3 = gtk_label_new("\346\260\221  \346\227\217");  
  261.   gtk_widget_show (label3);  
  262.   gtk_fixed_put (GTK_FIXED (fixed1), label3,280, 80);  
  263.   gtk_widget_set_size_request (label3, 64, 17);  
  264.    
  265.   label6 = gtk_label_new("\350\272\253\344\273\275\350\257\201\345\217\267");  
  266.   gtk_widget_show (label6);  
  267.   gtk_fixed_put (GTK_FIXED (fixed1), label6,16, 208);  
  268.   gtk_widget_set_size_request (label6, 69, 17);  
  269.    
  270.   label5 = gtk_label_new("\345\234\260  \345\235\200");  
  271.   gtk_widget_show (label5);  
  272.   gtk_fixed_put (GTK_FIXED (fixed1), label5,16, 168);  
  273.   gtk_widget_set_size_request (label5, 64, 17);  
  274.    
  275.   label4 = gtk_label_new("\347\224\237  \346\227\245");  
  276.   gtk_widget_show (label4);  
  277.   gtk_fixed_put (GTK_FIXED (fixed1), label4,16, 120);  
  278.   gtk_widget_set_size_request (label4, 64,17);   
  279.     
  280.    
  281.    
  282.   g_signal_connect ((gpointer) bt_close,"clicked",  
  283.                     G_CALLBACK(on_bt_close_clicked),  
  284.                     NULL);  
  285.                      
  286.   g_signal_connect ((gpointer) button1,"clicked",  
  287.                     G_CALLBACK(on_bt_ok_clicked),  
  288.                     NULL);  
  289.    
  290.   gtk_widget_show_all(window);    
  291.   gtk_main();  
  292.    
  293.   return 0;  
  294. }<span style="font-family:Arial,Helvetica,sans-serif; background-color:rgb(255,255,255)"> </span>  
//gtktest.c
#include<gtk/gtk.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#include<termio.h>
#include<unistd.h>
#include<errno.h>
#include<iconv.h>
#include<locale.h>
#include<ABCVlib.h> 
 
#defineTERM_TYPE       1                //终端类型 默认1
#defineTERM_PORT       1               //阅读机具所接的串口号
                                        //1:主机串口一
#defineTIMEOUT         4               //读卡超时4秒返回
#define BUFLEN 255 
 
  GtkWidget *window;
  GtkWidget *frame; 
  GtkWidget *label;
  GtkWidget *plus;
  GtkWidget *minus;
 
  GtkWidget *fixed1;
  GtkWidget *entrName;
  GtkWidget *entrSex;
  GtkWidget *label1;
  GtkWidget *entrNation;
  GtkWidget *entrBirthday;
  GtkWidget *entrAddr;
  GtkWidget *entrID;
  GtkWidget *entrDep;
  GtkWidget *entrValid;
  GtkWidget *label7;
  GtkWidget *label9;
  GtkWidget *hseparator1;
  GtkWidget *label2;
  GtkWidget *bt_close;
  GtkWidget *button1;
  GtkWidget *label3;
  GtkWidget *label6;
  GtkWidget *label5;
  GtkWidget *label4;
  GtkWidget *image;
 
//代码转换:从一种编码转为另一种编码
int code_convert(char*from_charset,char *to_charset,char *inbuf,int inlen,char *outbuf,int outlen)
{
   iconv_t cd;
   int rc;
   char **pin = &inbuf;
   char **pout = &outbuf;
 
   cd = iconv_open(to_charset,from_charset);
   if (cd==0) return -1;
   memset(outbuf,0,outlen);
   if (iconv(cd,pin,&inlen,pout,&outlen)==-1)return -1;
   iconv_close(cd);
   return 0;
}
//UNICODE码utf-8转为GB码
int u2g(char *inbuf,int inlen,char *outbuf,intoutlen)
{
   returncode_convert("utf-8","gb2312",inbuf,inlen,outbuf,outlen);
}
//GB码转为UNICODE码utf-8
int g2u(char*inbuf,size_t inlen,char *outbuf,size_t outlen)
{
   returncode_convert("gb2312","utf-8",inbuf,inlen,outbuf,outlen);
}
 
voidon_bt_close_clicked(GtkButton *button,gpointer user_data)
{
   gtk_main_quit();
}
 
voidon_bt_ok_clicked (GtkButton *button,gpointer user_data)
{
 
  inti,Len,nRet,zpLen;   
   unsigned char Buff[500];
   char outbuf[BUFLEN];
   unsigned char zpBuff[1024];
   char TMP[512];
   char *wltfile="./xp.wlt";
  char*bmpfile="./xp.bmp";     
  FILE*f;                           
                                   
 //调用libABCVLib.so 动态库阅读身份证,自动生成文字和照片文件                                 
  nRet =abcv_ReadIDCard (TERM_TYPE, TERM_PORT,TIMEOUT, Buff, &Len, zpBuff, &zpLen); //libABCVLib.so 
  if (nRet==0)
   {
         //显示姓名
           memset(TMP,'\0',512);   
          memset(outbuf,'\0',BUFLEN);       
          abcv_getName(TMP);         
          if ((i=g2u(TMP,strlen(TMP),outbuf,BUFLEN))==0 )
          {                
                 gtk_entry_set_text(GTK_ENTRY(entrName),outbuf); 
          }                                 
         
          //显示性别
          memset(TMP,'\0',512);                    
          abcv_getSex(TMP);
                
          if ((i=g2u(TMP,strlen(TMP),outbuf,BUFLEN))==0 )    
          {                             
              gtk_entry_set_text(GTK_ENTRY(entrSex), outbuf);
          }
          //显示民族
          memset(TMP,'\0',512);          
          abcv_getchNation(TMP);     
          if ((i=g2u(TMP,strlen(TMP),outbuf,BUFLEN))==0 )    
          {                             
              gtk_entry_set_text(GTK_ENTRY(entrNation), outbuf);
          }
         
          //显示出生日期      
          memset(TMP,'\0',512);                     
          abcv_getBirth(TMP);        
          if ((i=g2u(TMP,strlen(TMP),outbuf,BUFLEN))==0 )    
          {                             
              gtk_entry_set_text(GTK_ENTRY(entrBirthday), outbuf);
          }
         
          //显示户籍地址
          memset(TMP,'\0',512);             
          abcv_getAddr(TMP);             
          if ((i=g2u(TMP,strlen(TMP),outbuf,BUFLEN))==0 )    
          {                             
              gtk_entry_set_text(GTK_ENTRY(entrAddr), outbuf);
          }
         //显示身份证号码
          memset(TMP,'\0',512);             
          abcv_getIdCode(TMP);    
          if ((i=g2u(TMP,strlen(TMP),outbuf,BUFLEN))==0 )    
          {                             
              gtk_entry_set_text(GTK_ENTRY(entrID), outbuf);
          }
          //显示签发机关
          memset(TMP,'\0',512);                 
          abcv_getIssue(TMP);            
          if ((i=g2u(TMP,strlen(TMP),outbuf,BUFLEN))==0 )    
          {                             
              gtk_entry_set_text(GTK_ENTRY(entrDep), outbuf);
          }
          //显示证件有效期
          memset(TMP,'\0',512);             
          abcv_getValidity(TMP);                   
          if ((i=g2u(TMP,strlen(TMP),outbuf,BUFLEN))==0 )    
          {                             
              gtk_entry_set_text(GTK_ENTRY(entrValid), outbuf);
          }
             
          //显示身份证照片
          image =gtk_image_new_from_file(bmpfile);
          gtk_widget_set_size_request(image,102, 126);
          gtk_widget_show (image);     
          gtk_fixed_put (GTK_FIXED (fixed1),image, 438, 160);
                           
   }
   else {
       g_warning ("Error Code: %d", nRet);   
   }
}
 
  
 
int main(int argc,char** argv) {  
 
  gtk_init(&argc, &argv);
 
  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
  gtk_window_set_default_size (GTK_WINDOW(window), 580, 400);
  gtk_window_set_title(GTK_WINDOW(window),"Raspi IDCard2 Reader"); 
 
  fixed1 = gtk_fixed_new ();
  gtk_widget_show (fixed1);
  gtk_container_add (GTK_CONTAINER (window),fixed1);
  gtk_widget_set_size_request (fixed1, 286,123);
 
  entrName = gtk_entry_new ();
  gtk_widget_show (entrName);
  gtk_fixed_put (GTK_FIXED (fixed1), entrName,96, 16);
  gtk_widget_set_size_request (entrName, 158,25);
 
  entrSex = gtk_entry_new ();
  gtk_widget_show (entrSex);
  gtk_fixed_put (GTK_FIXED (fixed1), entrSex,96, 72);
  gtk_widget_set_size_request (entrSex, 84,25);
 
  label1 = gtk_label_new("\345\247\223  \345\220\215");
  gtk_widget_show (label1);
  gtk_fixed_put (GTK_FIXED (fixed1), label1, 8,23);
  gtk_widget_set_size_request (label1, 82, 17);
 
  entrNation = gtk_entry_new ();
  gtk_widget_show (entrNation);
  gtk_fixed_put (GTK_FIXED (fixed1),entrNation, 344, 72);
  gtk_widget_set_size_request (entrNation, 84,25);
 
  entrBirthday = gtk_entry_new ();
  gtk_widget_show (entrBirthday);
  gtk_fixed_put (GTK_FIXED (fixed1),entrBirthday, 96, 112);
  gtk_widget_set_size_request (entrBirthday,160, 25);
 
  entrAddr = gtk_entry_new ();
  gtk_widget_show (entrAddr);
  gtk_fixed_put (GTK_FIXED (fixed1), entrAddr,96, 160);
  gtk_widget_set_size_request (entrAddr, 331,25);
 
  entrID = gtk_entry_new ();
  gtk_widget_show (entrID);
  gtk_fixed_put (GTK_FIXED (fixed1), entrID,96, 200);
  gtk_widget_set_size_request (entrID, 331,25);
 
  entrDep = gtk_entry_new ();
  gtk_widget_show (entrDep);
  gtk_fixed_put (GTK_FIXED (fixed1), entrDep,96, 240);
  gtk_widget_set_size_request (entrDep, 331,25);
 
  entrValid = gtk_entry_new ();
  gtk_widget_show (entrValid);
  gtk_fixed_put (GTK_FIXED (fixed1), entrValid,96, 280);
  gtk_widget_set_size_request (entrValid, 331,25);
 
  label7 = gtk_label_new("\345\217\221\350\257\201\346\234\272\345\205\263");
  gtk_widget_show (label7);
  gtk_fixed_put (GTK_FIXED (fixed1), label7,16, 240);
  gtk_widget_set_size_request (label7, 68, 25);
 
  label9 = gtk_label_new("\346\234\211\346\225\210\346\234\237\351\231\220");
  gtk_widget_show (label9);
  gtk_fixed_put (GTK_FIXED (fixed1), label9,16, 280);
  gtk_widget_set_size_request (label9, 68, 17);
 
  hseparator1 = gtk_hseparator_new ();
  gtk_widget_show (hseparator1);
  gtk_fixed_put (GTK_FIXED (fixed1),hseparator1, 24, 312);
  gtk_widget_set_size_request (hseparator1,426, 16);
 
  label2 = gtk_label_new("\346\200\247  \345\210\253");
  gtk_widget_show (label2);
  gtk_fixed_put (GTK_FIXED (fixed1), label2,16, 80);
  gtk_widget_set_size_request (label2, 64, 17);
 
  bt_close = gtk_button_new_with_mnemonic("\351\200\200\345\207\272");
  gtk_widget_show (bt_close);
  gtk_fixed_put (GTK_FIXED (fixed1), bt_close,296, 336);
  gtk_widget_set_size_request (bt_close, 53,27);
 
  button1 = gtk_button_new_with_mnemonic("\350\257\273\345\215\241");
  gtk_widget_show (button1);
  gtk_fixed_put (GTK_FIXED (fixed1), button1,152, 336);
  gtk_widget_set_size_request (button1, 53, 27);
 
  label3 = gtk_label_new("\346\260\221  \346\227\217");
  gtk_widget_show (label3);
  gtk_fixed_put (GTK_FIXED (fixed1), label3,280, 80);
  gtk_widget_set_size_request (label3, 64, 17);
 
  label6 = gtk_label_new("\350\272\253\344\273\275\350\257\201\345\217\267");
  gtk_widget_show (label6);
  gtk_fixed_put (GTK_FIXED (fixed1), label6,16, 208);
  gtk_widget_set_size_request (label6, 69, 17);
 
  label5 = gtk_label_new("\345\234\260  \345\235\200");
  gtk_widget_show (label5);
  gtk_fixed_put (GTK_FIXED (fixed1), label5,16, 168);
  gtk_widget_set_size_request (label5, 64, 17);
 
  label4 = gtk_label_new("\347\224\237  \346\227\245");
  gtk_widget_show (label4);
  gtk_fixed_put (GTK_FIXED (fixed1), label4,16, 120);
  gtk_widget_set_size_request (label4, 64,17); 
  
 
 
  g_signal_connect ((gpointer) bt_close,"clicked",
                    G_CALLBACK(on_bt_close_clicked),
                    NULL);
                   
  g_signal_connect ((gpointer) button1,"clicked",
                    G_CALLBACK(on_bt_ok_clicked),
                    NULL);
 
  gtk_widget_show_all(window);  
  gtk_main();
 
  return 0;
}<span style="font-family:Arial,Helvetica,sans-serif; background-color:rgb(255,255,255)"> </span>

直接在树莓派上编译gtktest.c:

GTK+ Makefile文件:

  1. ARM_PREFIX=arm-linux-gnueabihf-  
  2. CC   = $(ARM_PREFIX)gcc  
  3. SRC += gtktest.c  
  4. TARGET = gtktest  
  5.    
  6. LIBRARY += gtk-3  
  7. LIBRARY += gdk-3  
  8. LIBRARY += atk-1.0  
  9. LIBRARY += gio-2.0  
  10. LIBRARY +=pangocairo-1.0  
  11. LIBRARY +=gdk_pixbuf-2.0  
  12. LIBRARY +=cairo-gobject  
  13. LIBRARY +=pango-1.0  
  14. LIBRARY += cairo  
  15. LIBRARY +=gobject-2.0  
  16. LIBRARY +=glib-2.0  
  17. LIBRARY += stdc++  
  18. LIBRARY+= ABCVLib  
  19. LIBRARY += dl  
  20.    
  21. LIBRARYDIR +=/lib/arm-linux-gnueabihf  
  22. LIBRARYDIR +=/usr/lib/arm-linux-gnueabihf  
  23. LIBRARYDIR += /lib  
  24. LIBRARYDIR +=/usr/lib  
  25.    
  26. #请改成你自己的工作目录  
  27. LIBRARYDIR+= /home/pi/kim/gtk30  
  28.    
  29. XLINK_LIBDIR +=/lib/arm-linux-gnueabihf  
  30. XLINK_LIBDIR +=/usr/lib/arm-linux-gnueabihf  
  31.    
  32. INCLUDEDIR +=/usr/include/gtk-3.0  
  33. INCLUDEDIR +=/usr/include/pango-1.0  
  34. INCLUDEDIR +=/usr/include/gio-unix-2.0/  
  35. INCLUDEDIR +=/usr/include/atk-1.0  
  36. INCLUDEDIR +=/usr/include/cairo  
  37. INCLUDEDIR +=/usr/include/gdk-pixbuf-2.0  
  38. INCLUDEDIR +=/usr/include/freetype2  
  39. INCLUDEDIR +=/usr/include/glib-2.0  
  40. INCLUDEDIR +=/usr/lib/arm-linux-gnueabihf/glib-2.0/include  
  41. INCLUDEDIR +=/usr/include/pixman-1  
  42. INCLUDEDIR +=/usr/include/libpng12  
  43. #请改成你自己的工作目录  
  44. INCLUDEDIR+= /home/pi/kim/gtk30  
  45.    
  46. OPT = -O0  
  47. DEBUG = -g  
  48. WARN= -Wall  -Wextra -pedantic  
  49. PTHREAD= -pthread  
  50.    
  51. INCDIR  = $(patsubst %,-I%,$(INCLUDEDIR))  
  52. LIBDIR  = $(patsubst %,-L%,$(LIBRARYDIR))  
  53. LIB    = $(patsubst %, -l%,$(LIBRARY))  
  54. XLINKDIR =$(patsubst %,-Xlinker -rpath-link=%,$(XLINK_LIBDIR))  
  55.    
  56. all:  
  57.    $(CC) $(OPT) $(DEBUG) $(WARN) $(LIBDIR)$(PTHREAD) $(INCDIR) $(XLINKDIR) $(LIB) $(SRC) -o $(TARGET)  
  58.    
  59. clean:  
  60.    rm -rf $(TARGET)  
ARM_PREFIX=arm-linux-gnueabihf-
CC   = $(ARM_PREFIX)gcc
SRC += gtktest.c
TARGET = gtktest
 
LIBRARY += gtk-3
LIBRARY += gdk-3
LIBRARY += atk-1.0
LIBRARY += gio-2.0
LIBRARY +=pangocairo-1.0
LIBRARY +=gdk_pixbuf-2.0
LIBRARY +=cairo-gobject
LIBRARY +=pango-1.0
LIBRARY += cairo
LIBRARY +=gobject-2.0
LIBRARY +=glib-2.0
LIBRARY += stdc++
LIBRARY+= ABCVLib
LIBRARY += dl
 
LIBRARYDIR +=/lib/arm-linux-gnueabihf
LIBRARYDIR +=/usr/lib/arm-linux-gnueabihf
LIBRARYDIR += /lib
LIBRARYDIR +=/usr/lib
 
#请改成你自己的工作目录
LIBRARYDIR+= /home/pi/kim/gtk30
 
XLINK_LIBDIR +=/lib/arm-linux-gnueabihf
XLINK_LIBDIR +=/usr/lib/arm-linux-gnueabihf
 
INCLUDEDIR +=/usr/include/gtk-3.0
INCLUDEDIR +=/usr/include/pango-1.0
INCLUDEDIR +=/usr/include/gio-unix-2.0/
INCLUDEDIR +=/usr/include/atk-1.0
INCLUDEDIR +=/usr/include/cairo
INCLUDEDIR +=/usr/include/gdk-pixbuf-2.0
INCLUDEDIR +=/usr/include/freetype2
INCLUDEDIR +=/usr/include/glib-2.0
INCLUDEDIR +=/usr/lib/arm-linux-gnueabihf/glib-2.0/include
INCLUDEDIR +=/usr/include/pixman-1
INCLUDEDIR +=/usr/include/libpng12
#请改成你自己的工作目录
INCLUDEDIR+= /home/pi/kim/gtk30
 
OPT = -O0
DEBUG = -g
WARN= -Wall  -Wextra -pedantic
PTHREAD= -pthread
 
INCDIR  = $(patsubst %,-I%,$(INCLUDEDIR))
LIBDIR  = $(patsubst %,-L%,$(LIBRARYDIR))
LIB    = $(patsubst %, -l%,$(LIBRARY))
XLINKDIR =$(patsubst %,-Xlinker -rpath-link=%,$(XLINK_LIBDIR))
 
all:
   $(CC) $(OPT) $(DEBUG) $(WARN) $(LIBDIR)$(PTHREAD) $(INCDIR) $(XLINKDIR) $(LIB) $(SRC) -o $(TARGET)
 
clean:
   rm -rf $(TARGET)

3.4 身份证阅读运行效果(在电脑VNC显示读卡界面)

依次输入:

  1. <pre class="plain" name="code">$make  
  2. $./gtktest</pre>  
<div class="dp-highlighter bg_plain"><div class="bar"><div class="tools"><strong>[plain]</strong> <a target=_blank title="view plain" class="ViewSource" href="http://blog.csdn.net/kimwu/article/details/12654517#">view plain</a><span data-mod="popu_168"> <a target=_blank title="copy" class="CopyToClipboard" href="http://blog.csdn.net/kimwu/article/details/12654517#">copy</a></span><div style="left: 0px; top: 0px; width: 0px; height: 0px; position: absolute; z-index: 99;"></div><span data-mod="popu_169"> <a target=_blank title="print" class="PrintSource" href="http://blog.csdn.net/kimwu/article/details/12654517#">print</a></span><a target=_blank title="?" class="About" href="http://blog.csdn.net/kimwu/article/details/12654517#">?</a></div></div><ol><li class="alt"><span><span>$make  </span></span></li><li><span>$./gtktest  </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div></div><pre class="plain" style="display: none;" name="code">$make
$./gtktest
 


当然也可直接在安卓手机VNC界面下打开阅读界面并显示读卡结果:

 

 

 

附:用Lazarus Pascal设计树莓派下图形界面:


还可在Windows环境下交叉设计编译,正如其所说的一次编译到处运行:


在Windows下执行Lazarus设计的程序:


四、扩展应用

与手机结合、触摸屏、摄像头、指纹头、打印机、蓝牙、NFC…

 

 

五、市场前景

该设备应用领域:自助设备、手持设备、物联网、安防门禁…

 

适用范围:

●公安:身份证申领、户口登记迁移、人口管理等。 旅馆:住宿登记等。

●民政:求学、就业、参军、婚姻登记等。

●民航:机票购买、登机等。

●银行:开户、信用卡交易、大额取款等。

●邮局:领取邮件汇款等。

●电信:电话手机开户、各种通信业务等。

●证券:股票、期货交易等。

●企事业单位:招工、来访登记

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值