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.最后說一下,啟動函數里面使用了阻塞,讓我的實例不掛掉