用Go语言在Linux下调用新中新DKQ-A16D读卡器,读二代证数据

1.背景

前几天用Python在Linux下成功的获取了二代证数据,最近正在学Go语言,这两天想着用Go语言也实现一下试看看。

2.开搞C++

这次就比较简单了,直接把CppDemo里面的SynReader.h拿来就可以,还有就是把CppDemo里面的lib文件也复制过来就可以,

具体流程和Python那篇文章的一样

被我精简后的SynReader.h

#ifndef SYN_READER_H
#define SYN_READER_H

#ifdef __cplusplus
extern "C" {
#endif



#pragma pack(1)

typedef struct IDCardDataUTF8 {
    char CardType[10];         //I为外国人居住证,J 为港澳台居住证,空格(0x20)为普通身份证
    char Name[40];             //姓名 
    char EngName[130];       //英文名(外国人居住证)
    char Sex[10];           //性别
    char Nation[100];          //民族或国籍(外国人居住证)     
    char Birthday[18];         //出生日期
    char Address[80];       //住址
    char IDCardNo[40];      //身份证号或外国人居住证号(外国人居住证)
    char GrantDept[40];     //发证机关
    char UserLifeBegin[30]; //有效开始日期
    char UserLifeEnd[30];   //有效截止日期
    char PassID[30];        //通行证号码(港澳台)
    char IssuesTimes[10];    //签发次数(港澳台)
    char CertVol[10];         //证件版本号(外国人居住证)
    char wlt[1024];           //照片数据
    int isSavePhotoOK;        //照片是否解码保存  0=no  1=yes
    char fp[1024];            //指纹数据
    int isFpRead;            //是否读取了证内指纹     0=no 1=yes
} St_IDCardDataUTF8, *PSt_IDCardDataUTF8;
#pragma pack()

//读身份证文字和照片信息
int getIDcard(St_IDCardDataUTF8 *pIDCardDataUTF8);

int OpenUsbComm();
int OpenSerialComm(const char*);
int CloseComm();


//解码照片函数,wltBuffer原始照片1024字节wlt数据,bmpPath 保存照片位置
int saveWlt2Bmp( char* wltBuffer,const char* bmpPath);
int saveWlt2BmpUseFork( char* wltBuffer,const char* bmpPath);

//获取动态库版本
const char* getLibVersion();
int getLibVersionInt();



#ifdef __cplusplus
}
#endif

#endif

3.开搞Go

直接上代码了,大概的分析和Python的差不多,在Go语言中,主要是用到import "C"这个东东来调用C语言里面的函数

main.go

package main

/*
#cgo  LDFLAGS:  -L ./lib  -lSynReader64
#include "../include/SynReader64.h"
*/
import "C"
import (
    "fmt"
    "unsafe"
)

/*
CArrayToGoString 将C语言中的字符数组转为Go语言的string
*/
func CArrayToGoString(cArray unsafe.Pointer, size int) (goStr string) {
    p := uintptr(cArray)
    var goArray []byte
    for i := 0; i < size; i++ {
        j := *(*byte)(unsafe.Pointer(p))
        goArray = append(goArray, j)
        p += unsafe.Sizeof(j)
    }

    return string(goArray)
}

func main() {

    var stIDCardDataUTF8 C.struct_IDCardDataUTF8

    openState := C.OpenUsbComm()

    if openState == 0 {
        getState := C.getIDcard(&stIDCardDataUTF8)

        if getState == 0 {
            strName := CArrayToGoString(unsafe.Pointer(&stIDCardDataUTF8.Name), 40)
            strSex := CArrayToGoString(unsafe.Pointer(&stIDCardDataUTF8.Sex), 10)
            strNation := CArrayToGoString(unsafe.Pointer(&stIDCardDataUTF8.Nation), 100)
            strBirthday := CArrayToGoString(unsafe.Pointer(&stIDCardDataUTF8.Birthday), 18)
            strAddress := CArrayToGoString(unsafe.Pointer(&stIDCardDataUTF8.Address), 80)
            strIDCardNo := CArrayToGoString(unsafe.Pointer(&stIDCardDataUTF8.IDCardNo), 40)
            strGrantDept := CArrayToGoString(unsafe.Pointer(&stIDCardDataUTF8.GrantDept), 40)
            strUserLifeBegin := CArrayToGoString(unsafe.Pointer(&stIDCardDataUTF8.UserLifeBegin), 30)
            strUserLifeEnd := CArrayToGoString(unsafe.Pointer(&stIDCardDataUTF8.UserLifeEnd), 30)

            fmt.Println(strName)
            fmt.Println(strSex)
            fmt.Println(strNation)
            fmt.Println(strBirthday)
            fmt.Println(strAddress)
            fmt.Println(strIDCardNo)
            fmt.Println(strGrantDept)
            fmt.Println(strUserLifeBegin)
            fmt.Println(strUserLifeEnd)

            photoData := unsafe.Pointer(&stIDCardDataUTF8.wlt)
            C.saveWlt2BmpUseFork((*C.char)(photoData), C.CString("Photo.bmp"))
        }

    }
    C.CloseComm()

}

其中注意,第4行,作用是引入so库,-l参数后面加so文件名(不含.so)

第5行是引入C++定义的头文件

具体路径目录如下:

├── include
│   └── SynReader64.h
├── libx64
│   ├── libSynReader64.so
│   ├── libusb-1.0.so
│   └── libwlt.so
└── src
├── main
└── main.go

4.结束

相关推荐