使用jna调用c语言动态库对接华视电子身份证阅读机

2022-10-25 16:07:15 浏览数 (2)

一些C语言的接口见上一篇文章 同样把用到的动态库放到jdk的bin目录文件夹下 Termb.java

代码语言:javascript复制
import com.sun.jna.Library;
import com.sun.jna.Native;

public interface Termb extends Library {

    Termb instanceDll  = (Termb) Native.loadLibrary("Termb",Termb.class);

    int CVR_InitComm(int Port);
    int CVR_Authenticate();
    int CVR_Read_Content(int active);

    int  GetPeopleIDCode(byte[] strTmp, byte[] strLen);

}

测试类:

代码语言:javascript复制
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xvolks.jnative.JNative;
import org.xvolks.jnative.Type;
import org.xvolks.jnative.exceptions.NativeException;
import org.xvolks.jnative.pointers.Pointer;
import org.xvolks.jnative.pointers.memory.MemoryBlockFactory;

import java.io.UnsupportedEncodingException;

/**
 * @author: xiepanpan
 * @Date: 2020/5/14
 * @Description:
 */
public class TestCVR {
    static Logger logger = LoggerFactory.getLogger(TestCVR.class);

    static String strTmp = "";

    public static void main(String[] args) {

        //1.打开端口
        try
        {
            int portReturnCode = Termb.instanceDll.CVR_InitComm(1001);
            System.out.println("打开端口返回值:"   String.valueOf(portReturnCode));
            if (portReturnCode!=1) {
            }
        }
        catch(Exception ex)
        {
            logger.error("打开端口调用异常!"  ex.getMessage());
        }
        try {
            System.out.println("请放置身份证。。。");
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


        // 2. 认证
        int authReturnCode = 0;
        try
        {
            authReturnCode = Termb.instanceDll.CVR_Authenticate();
            System.out.println("认证返回值:"   String.valueOf(authReturnCode));
            if (authReturnCode!=1) {
            }
        }
        catch(Exception ex)
        {
            logger.error("认证调用异常!"  ex.getMessage());
        }

        //3. 读卡
        int readReturnCode = 0;
        try
        {
            readReturnCode = Termb.instanceDll.CVR_Read_Content(4);
            System.out.println("读卡返回值:"   String.valueOf(readReturnCode));
            if (authReturnCode!=1) {
            }
        }
        catch(Exception ex)
        {
            logger.error("读卡调用异常!"  ex.getMessage());
        }

        //4. 读取身份证号码
        int readIdReturnCode = 0;
        try
        {
            byte[] a = new byte[4*10];
            byte[] b = new byte[4*30];
            readIdReturnCode = Termb.instanceDll.GetPeopleIDCode(a,b);
            System.out.println("读取身份证号码返回值:"   String.valueOf(readIdReturnCode));
            if(readIdReturnCode == 1)
            {
                System.out.println("身份号码读取成功:"   new String(a));


            }
        }
        catch(Exception ex)
        {
            logger.error("调用异常!"  ex.getMessage());
        }
    }

}

那如果是web工程呢 有的小朋友说了我就不把动态库放到bin目录下边 能行么

答案是可以的 这里贴一下我的web工程的代码 目录结构:

接口Termb

代码语言:javascript复制
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.thunisoft.jy.ywgk.zf.utils.D5ScannerS77;

/**
 *  @author: xiepanpan
 *  @Date: 2020/5/14
 *  @Description:  调用身份证读卡器的动态库
 */
public interface Termb extends Library {
    //绝对路径的地址获取,注意要去空格
    String filePath = Termb.class.getResource("").getPath().replaceFirst("/","")
            .replaceAll(" "," ") "termb.dll";
    //先加载这两个dll
    UnPack UN_PACK = UnPack.instanceDll;
    Sdtapi SDTAPI = Sdtapi.instanceDll;
    Termb instanceDll  = (Termb) Native.loadLibrary(filePath,Termb.class);
    /**
     * 	初始化连接
     * @param Port
     * @return
     */
    int CVR_InitComm(int Port);

    /**
     * 	卡认证
     * @return
     */
    int CVR_Authenticate();

    /**
     * 	读卡操作
     * @param active
     * @return
     */
    int  CVR_Read_Content(int active);

    /**
     * 得到卡号信息
     * @param strTmp 返回的信息缓存指针
     * @param strLen 返回的信息长度指针
     * @return
     */
    int  GetPeopleIDCode(byte[] strTmp, byte[] strLen);

}

接口Sdtapi

代码语言:javascript复制
import com.sun.jna.Library;
import com.sun.jna.Native;

/**
 *  @author: xiepanpan
 *  @Date: 2020/5/15
 *  @Description: 安全模块通讯函数
 */
public interface Sdtapi extends Library {
    //绝对路径的地址获取,注意要去空格
    String filePath = Sdtapi.class.getResource("").getPath().replaceFirst("/","")
            .replaceAll(" "," ") "sdtapi.dll";
    Sdtapi instanceDll  = (Sdtapi) Native.loadLibrary(filePath,Sdtapi.class);
}

接口UnPack

代码语言:javascript复制
import com.sun.jna.Library;
import com.sun.jna.Native;

/**
 *  @author: xiepanpan
 *  @Date: 2020/5/15
 *  @Description: 身份证相片解码库
 */
public interface UnPack extends Library {
    //绝对路径的地址获取,注意要去空格
    String filePath = UnPack.class.getResource("").getPath().replaceFirst("/","")
            .replaceAll(" "," ") "UnPack.dll";
    UnPack instanceDll  = (UnPack) Native.loadLibrary(filePath,UnPack.class);
}

关键代码:

代码语言:javascript复制
	//绝对路径的地址获取,注意要去空格
    String filePath = Termb.class.getResource("").getPath().replaceFirst("/","")
            .replaceAll(" "," ") "termb.dll";
    //先加载这两个dll
    UnPack UN_PACK = UnPack.instanceDll;
    Sdtapi SDTAPI = Sdtapi.instanceDll;
    Termb instanceDll  = (Termb) Native.loadLibrary(filePath,Termb.class);

一个接口对应一个dll文件 因为Termb.dll文件依赖UnPack.dll 和sdtapi.dll 因此加载Termb.dll 先加载

java与C语言 参数类型的映射关系:

出处: https://github.com/java-native-access/jna/edit/master/www/Mappings.md

参考博客: https://www.cnblogs.com/digdeep/p/5288215.html

0 人点赞