1.启动类及其 如何调用c++的dll文件
import com.sun.jna.Callback; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.win32.StdCall; import lombok.extern.log4j.Log4j2; @Log4j2 public class Test { CLibrary cLibrary; public interface CLibrary extends Library, StdCall { CLibrary INSTANCE = (CLibrary) Native.loadLibrary("D:\subway\MicsDataSdk\MicsDataSdk.dll", CLibrary.class); void CMicsDataSDK(); //获取版本号 String Common_GetVersion(); //初始化 int Common_Init(String configPath, String logPath); int Common_Start(); int Common_Stop(); int Common_SetCallback(CLibrary xx, Callback back); } public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(()->{ String configPath="D:\project\MicsDataSdk\config.ini"; String logPath=""; CLibrary.INSTANCE.CMicsDataSDK(); CLibrary.INSTANCE.Common_Init(configPath,logPath); IMyDllCallback callback = new MyDllCallbackImpl(); String s = CLibrary.INSTANCE.Common_GetVersion(); System.out.println(s); CLibrary.INSTANCE.Common_SetCallback(null,callback); CLibrary.INSTANCE.Common_Start(); log.info("sdk启动"); synchronized (callback) { try { System.out.println("进入阻塞,等待数据中..."); callback.wait(); System.out.println("阻塞完成"); } catch (InterruptedException e) { e.printStackTrace(); } } }); thread.run(); } }
2.要设置回调函数,接口必须继承
import com.sun.jna.Callback;
而且接口里面只能有一个方法,回调接口
import com.sun.jna.Callback; import com.sun.jna.Pointer; import com.sun.jna.win32.StdCallLibrary; import java.io.UnsupportedEncodingException; /** * @author XWF * */ public interface IMyDllCallback extends StdCallLibrary.StdCallCallback { int OnCallback2(Callback Context, int LinkStatus, Pointer Points, int Size) throws UnsupportedEncodingException; }
3.实现类,c++的指针数组,在jna里面用
com.sun.jna.Pointer;接收,不能用数组接收
import com.sun.jna.Callback; import com.sun.jna.Pointer; import com.sun.jna.Structure; import lombok.extern.log4j.Log4j2; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; /** * @author XWF * */ @Log4j2 public class MyDllCallbackImpl implements IMyDllCallback { @Override public int OnCallback2(Callback element, int LinkStatus, Pointer data, int size) throws UnsupportedEncodingException { log.info("收到数据长度:"+size); List<Element> elementList = pointer2Structure(data, Element.class,size); List<ElementVo> voList = new ArrayList<>(); for (Element element1 : elementList) { ElementVo vo = new ElementVo(); int subSystem = element1.getSubSystem(); String addr = new String(element1.getAddr(),"GB2312"); String value = new String(element1.getValue(),"GB2312"); vo.setSubSystem(subSystem); vo.setAddr(addr); vo.setValue(value); voList.add(vo); } log.info("数据为:"+voList); return 0; } public static <Element extends Structure> List<Element> pointer2Structure(Pointer pParam, Class<Element> res,int arraySize) { List<Element> list = new ArrayList<>(); for (int k=0;k<arraySize;k++){ try { Element Param = res.newInstance(); Pointer facePointer = Param.getPointer(); byte[] byteArray = pParam.getByteArray(Param.size()*k, Param.size()); facePointer.write(0,byteArray,0,Param.size()); Param.read(); list.add(Param); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } return list; } /** * byte[]转int * @param bytes * @return */ public static int byteArrayToInt(byte[] bytes) { int value = 0; // 由高位到低位 for (int i = 0; i < 4; i++) { int shift = (4 - 1 - i) * 8; value += (bytes[i] & 0x000000FF) << shift;// 往高位游 } return value; } }
c++如果自己实现回调,回调demo如下
//回调函数。 context 任意一个对象 static int OnCallbackFun(void* context, int linkStatus,TDELEMENT *pointArray,int size) { if (size) { for (int index = 0; index < size; ++index) { TDELEMENT el = pointArray[index]; } } return size; }
4.指针数组对应的解析对象
package org.springblade.subway.vo.jnaTest; import com.sun.jna.Structure; import lombok.Data; import lombok.ToString; import java.util.ArrayList; import java.util.List; @Data public class Element extends Structure { public int SubSystem; public byte[] Addr = new byte[16]; public byte[] Value = new byte[16]; public static class ByReference extends Element implements Structure.ByReference {} public static class ByValue extends Element implements Structure.ByValue {} @Override public List getFieldOrder(){ List a = new ArrayList(); a.add("SubSystem"); a.add("Addr"); a.add("Value"); return a; } }
vo对象
@Data public class ElementVo { int SubSystem; String Addr; String Value; }
5.最后说一下,启动函数里面使用了阻塞,让我的实例不挂掉