springboot 使用 JNA 调用 DLL

1.添加依赖

<!-- Java Native Access -->
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
</dependency>

2.编写代码

加载dll,将dll文件放在resources文件夹下,启动项目配置项添加 VM options:-Djna.library.path = C:\Users\admin\project\src\main\resources\Lib

创建接口加载该dll:

public interface SuctionCardReaderService extends Library{
	SuctionCardReaderService Instance = Native.loadLibrary("ID81DLL", SuctionCardReaderService.class);
}

二代证电子信息结构体宏定义:

typedef struct IDInfo
{
    char name[32];		//姓名 
    char sex[4];		//性别
    char nation[12];	//民族
    char birthday[20];	//出生日期
    char address[72];	//住址信息
    char number[40];	//身份证号码
    char department[32];//签发机关
    char timeLimit[36];	//有效日期
    char Image[256];	//头像信息
}IDInfo;

创建相关实体类:

public class IDInfo extends Structure {
    /**
     * 姓名
     */
    public byte[] name = new byte[32];
    /**
     * 性别
     */
    public byte[] sex = new byte[4];
    /**
     * 民族
     */
    public byte[] nation = new byte[12];
    /**
     * 出生日期
     */
    public byte[] birthday = new byte[20];
    /**
     * 住址信息
     */
    public byte[] address = new byte[72];
    /**
     * 身份证号码
     */
    public byte[] number = new byte[40];
    /**
     * 签发机关
     */
    public byte[] department = new byte[32];
    /**
     * 有效日期
     */
    public byte[] timeLimit = new byte[36];
    /**
     * 头像信息
     */
    public byte[] Image = new byte[256];

    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList(new String[]{"name", "sex", "nation", "birthday", "address", "number", "department", "timeLimit", "Image"});
    }
}

设备信息结构体宏定义:

typedef struct ScannerInfoRec
{
    unsigned DeviceID;	//设备ID
}ScannerInfoRec;

创建相关实体类:

public class ScannerInfoRec extends Structure {

    public int DeviceID;

    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList(new String[]{"DeviceID"});
    }

}

dll中相关方法定义:

枚举扫描设备USB内部ID号
    int EnumScannerDevice(ScannerInfoRec *ScannerInfo, unsigned *DeviceNumber)
形式参数
    ScannerInfo:[输出] 获取USB设备内部ID号的结构体,内部ID号取值范围0-16。
    DeviceNumber:[输出] 枚举到的设备数量,不能为空。
打开设备
    int OpenConnection(unsigned DeviceID)
形式参数
    DeviceID:[输入] USB设备内部ID号,取值范围0-16。
读取当前图像数据块到内存
    int SavePicToMemory(unsigned DeviceID, char* cFrontImgBuf,char* cRearImgBuf, int* iFrontLen, int* iRearLen)
形式参数
    DeviceID:[输入] USB设备内部ID号,取值范围0-16。
    cFrontImgBuf:[输出] 保存正面图像数据信息指针,不能为空。
    cRearImgBuf:[输出] 保存反面图像数据信息指针,不能为空。
    iFrontLen:[输出] 正面图像数据长度。
    iRearLen:[输出] 反面图像数据长度。
获取二代证信息
    int GetID2Info(unsigned DeviceID, IDInfo *mIDInfo, char *HeadImageName)
形式参数
    DeviceID:[输入] USB设备内部ID号,取值范围0-16。
    mIDInfo:[输出] 身份证信息结构体指针,不能为空。
    HeadImageName:[输入] 图像名称,如果只传入路径则按照配置文件项HeadImgName动态名称[0-姓名+生日,1-身份证号]。 

在接口中新建对应方法:

	/**
     * 枚举设备
     * @param ScannerInfo
     * @param DeviceNumber
     * @return
     */
    int EnumScannerDevice(ScannerInfoRec[] ScannerInfo, IntByReference DeviceNumber);

    /**
     * 打开设备
     * @param DeviceID
     * @return
     */
    int OpenConnection(int DeviceID);
    
    /**
     * 读取当前图像数据块到内存
     * @param DeviceID
     * @return
     */
    int SavePicToMemory(int DeviceID, Pointer cFrontImgBuf, Pointer cRearImgBuf, IntByReference iFrontLen, IntByReference iRearLen);

    /**
     * 获取身份证信息
     * @param DeviceID
     * @param mIDInfo
     * @param HeadImageName
     * @return
     */
    int GetID2Info(int DeviceID, IDInfo mIDInfo, String HeadImageName);

调用接口

	/**
     * 获取二代证信息
     */
    @GetMapping("/getPersonalInfo")
    public ResponseEntity<PersonalInfo> getPersonalInfo() {
        //设备ID
        Integer deviceID = null;
        PersonalInfo personalInfo = new PersonalInfo();
        try {
            //枚举设备获取设备ID
            ScannerInfoRec[] deviceArray = (ScannerInfoRec[]) new ScannerInfoRec().toArray(1);
            IntByReference deviceNumber = new IntByReference();
            int enumScannerDevice = SuctionCardReaderService.Instance.EnumScannerDevice(deviceArray, deviceNumber);
            if (enumScannerDevice == SuctionCardReaderService.IDDIGITALCOPIER_NO_ERROR && deviceNumber.getValue() > 0) {
                for (ScannerInfoRec rec : deviceArray) {
                    deviceID = rec.DeviceID;
                }
                log.info("deviceID -- "+ deviceID);
                //连接设备
                int openConnection = SuctionCardReaderService.Instance.OpenConnection(deviceID);
                log.info("openConnection -- "+ openConnection);
                //获取身份证信息
                IDInfo idInfo = new IDInfo();
                int getID2Info = SuctionCardReaderService.Instance.GetID2Info(deviceID, idInfo, SuctionCardReaderService.HEAD_IMAGE_NAME);
                log.info("getID2Info -- "+ getID2Info);
                //获取个人信息成功
                if (getID2Info == SuctionCardReaderService.IDDIGITALCOPIER_NO_ERROR) {
                    personalInfo.setName(StringUtils.replace(new String(idInfo.name), "\u0000", ""));
                    personalInfo.setNumber(StringUtils.replace(new String(idInfo.number), "\u0000", ""));
                    personalInfo.setAddress(StringUtils.replace(new String(idInfo.address), "\u0000", ""));
                    personalInfo.setBirthday(StringUtils.replace(new String(idInfo.birthday), "\u0000", ""));
                    personalInfo.setDepartment(StringUtils.replace(new String(idInfo.department), "\u0000", ""));
                    personalInfo.setNation(StringUtils.replace(new String(idInfo.nation), "\u0000", ""));
                    personalInfo.setSex(StringUtils.replace(new String(idInfo.sex), "\u0000", ""));
                    personalInfo.setTimeLimit(StringUtils.replace(new String(idInfo.timeLimit), "\u0000", ""));
                    personalInfo.setImage(Base64Utils.encodeToString(Files.readAllBytes(Paths.get(SuctionCardReaderService.HEAD_IMAGE_NAME))));
                }
                //读取当前图像数据块到内存
                Pointer cFrontImgBuf = new Memory(16*1024*1024);
                Pointer cRearImgBuf = new Memory(16*1024*1024);
                IntByReference iFrontLen = new IntByReference();
                IntByReference iRearLen = new IntByReference();
                int savePicToMemory = SuctionCardReaderService.Instance.SavePicToMemory(deviceID, cFrontImgBuf, cRearImgBuf, iFrontLen, iRearLen);
                log.info("savePicToMemory -- "+ savePicToMemory);
                //保存身份证正反照照片
                personalInfo.setImagePositive(Base64Utils.encodeToString(cFrontImgBuf.getByteArray(0, iFrontLen.getValue())));
                personalInfo.setImageContrary(Base64Utils.encodeToString(cRearImgBuf.getByteArray(0, iRearLen.getValue())));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (deviceID == null) {
                log.info("未找到设备.");
            } 
        }
        return ResponseEntity.ok(personalInfo);
    }

注:
若需要把项目打包成jar运行,将dll文件至于jar包同目录,编辑start.bat文件 :start jre1.8.0_221/bin/java -Djna.library.path=./Lib -jar project.jar

你可能感兴趣的:(SpringBoot)