JNA 실천

19089 단어 java 기초

JNA 사용 요약

  • 환경 구축


  • 1. JDK 버전의 자릿수, DLL 자릿수와 일치해야 합니다. 그렇지 않으면 다음 오류로 돌아갑니다.
    "Exception in thread"main"Java.lang. UnsatisfiedLink Error: Unable to load library"RWBIF.dll": 지정된 모듈을 찾을 수 없습니다."2. JAVA DLL 경로 지정
  • sample1: 대응하는 DLL은 컴파일된 bin 디렉터리에 두어야 한다
    public static String DEFAULT_NXT_DLL_NAME = "RWBIF";
    
    NxtService nxtServiceInstance = Native.loadLibrary(DEFAULT_NXT_DLL_NAME,
      NxtService.class);
    
    
  • sample2: 절대 경로 지정
    NxtManager.programName = "C:\\java\\code\
    xt_plus\\RWBIF.dll"; NxtService nxtServiceInstance = (NxtService) Native.loadLibrary(NxtManager.programName, NxtService.class);
  • 3. jar 패키지 사용
        // https://mvnrepository.com/artifact/net.java.dev.jna/jna  
    	compile group: 'net.java.dev.jna', name: 'jna', version: '4.5.0'
    
  • JNA 사용


  • 1. Java 및 JNA 유형 매핑http://java-native-access.github.io/jna/4.4.0/javadoc/overview-summary.html#structures2. Java 및 JNA 기본 유형 매핑
  • char(c,c++,8it) —> byte(java,8bit) C++
  • ```
    typedef struct _tag_RWBIF_PANELIDINFO_EX
    {
        TCHAR szBarcode[68];//typedefine char TCHAR
        INT nLane;
    } RWBIF_PANELIDINFO_EX, *PRWBIF_PANELIDINFO_EX;
    ```
    
    
    Java:  
    
    public static class RWBIF_PANELIDINFO_EX extends Structure {
    
       	public byte[] szBarcode = new byte[68];
    
       	public int nLane;
    
       	@Override
       	protected List getFieldOrder() {
       		// TODO Auto-generated method stub
       		return Arrays.asList(new String[] { "szBarcode", "nLane" });
       	}
    
       }
       
       [ ]:fileOrder        
    

    구조체 구조체 포인터나 구조체 인용을 호출하여 Structure를 실현합니다.ByReference 직접 전송은 Structure를 실현해야 합니다.ByValue
    C++
    
    typedef struct _tag_RWBIF_AUTO_JOB_CHG_RESULT
    {
    	TCHAR szMcName[32];
    	DWORD dwErrorCode;
    } RWBIF_AUTO_JOB_CHG_RESULT, *PRWBIF_AUTO_JOB_CHG_RESULT;
    
    
    
    java   
    public static class RWBIF_AUTO_JOB_CHG_RESULT extends Structure {
    
    		public static class ByReference extends RWBIF_AUTO_JOB_CHG_RESULT implements Structure.ByReference {
    		}
    
    		public static class ByValue extends RWBIF_AUTO_JOB_CHG_RESULT implements Structure.ByValue {
    		}
    
    		public byte[] szMcName = new byte[32];
    
    		public int dwErrorCode;
    
    		@Override
    		protected List getFieldOrder() {
    			// TODO Auto-generated method stub
    			return Arrays.asList(new String[] { "szMcName", "dwErrorCode" });
    		}
    	}
    

    복잡한 구조체, 그 구성원 함수는 구조체의 지침이나 인용을 포함한다
    C++
    
    typedef struct _tag_RWBIF_HELPS_CHGOVERJOB
    {
    	INT nLane;
    	RWBIF_JOBINFO_EX stJob;
    } RWBIF_HELPS_CHGOVERJOB, *PRWBIF_HELPS_CHGOVERJOB;
       RWBIF_JOBINFO_EX        ,      
    
    
    java  
    public static class PRWBIF_HELPS_CHGOVERJOB extends Structure {
    
    		public static class ByReference extends PRWBIF_HELPS_CHGOVERJOB implements Structure.ByReference {
    		}
    		public static class ByValue extends PRWBIF_HELPS_CHGOVERJOB implements Structure.ByValue {
    		}
    		public int nLane;
    
    		public RWBIF_JOBINFO_EX stJob;
    
    		@Override
    		protected List getFieldOrder() {
    			// TODO Auto-generated method stub
    			return Arrays.asList(new String[] { "nLane", "stJob" });
    		}
    
    	}
    
    
  • 포인터 유형은 int형 포인터를 사용하여 IntByReference
  • 3. 함수 매핑 구조체 바늘 매핑, 자바에서 설명한 인터페이스를 구조체 그룹으로 대체할 수 있습니다. 되돌아오는 값, 함수 이름을 포함해야 합니다.유형 매핑과 매개변수 이름이 같아야 합니다
  • .
    C++
    
    typedef INT (*pChangeOverJob)(LPCTSTR szSrv, LPCTSTR szLine, LPCTSTR szEquip, INT nJobChgMode, INT nQty, INT nSize, PRWBIF_HELPS_CHGOVERJOB pArg);
       PRWBIF_HELPS_CHGOVERJOB        , java             
    
    java
    int iChangeOverJob(String szSrv, String szLine, String szEquip, int nJobChgMode, int nQty, int nSize,
    			PRWBIF_HELPS_CHGOVERJOB[] pArg);
    				PRWBIF_HELPS_CHGOVERJOB[] pArg       
    

    복합 매개변수:포인터 참조, JNA 매개변수 대체
    C++
    
    typedef INT (*pGetAutoJobChgResult)(PRWBIF_AUTO_JOB_CHG_RESULT &rval);
       PRWBIF_AUTO_JOB_CHG_RESULT       ,    byReference[]    
    
    int iGetAutoJobChgResult(RWBIF_AUTO_JOB_CHG_RESULT.ByReference[] rval);
    
    
    
  • 참조 예제
  • JNA  :C++    
    public interface NxtService extends Library {
    
    
    
    	/** The default nxt dll name. */
    	public static String DEFAULT_NXT_DLL_NAME = "RWBIF";
    
    	/**
    	 * The Class _tag_RWBIF_PANELIDINFO_EX.
    	 */
    	public static class RWBIF_PANELIDINFO_EX extends Structure {
    
    		public byte[] szBarcode = new byte[68];
    
    		public int nLane;
    
    		@Override
    		protected List getFieldOrder() {
    			// TODO Auto-generated method stub
    			return Arrays.asList(new String[] { "szBarcode", "nLane" });
    		}
    
    	}
    
    	public static class RWBIF_AUTO_JOB_CHG_RESULT extends Structure {
    
    		public static class ByReference extends RWBIF_AUTO_JOB_CHG_RESULT implements Structure.ByReference {
    		}
    
    		public static class ByValue extends RWBIF_AUTO_JOB_CHG_RESULT implements Structure.ByValue {
    		}
    
    		public byte[] szMcName = new byte[32];
    
    		public int dwErrorCode;
    
    		@Override
    		protected List getFieldOrder() {
    			// TODO Auto-generated method stub
    			return Arrays.asList(new String[] { "szMcName", "dwErrorCode" });
    		}
    	}
    
    	public static class RWBIF_JOBINFO_EX extends Structure {
    
    		public static class ByReference extends RWBIF_JOBINFO_EX implements Structure.ByReference {
    		}
    		public static class ByValue extends RWBIF_JOBINFO_EX implements Structure.ByValue {
    		}
    		public byte[] szJobName = new byte[128];
    
    		public byte[] szRevision = new byte[16];
    
    		public int nSide;
    
    		@Override
    		protected List getFieldOrder() {
    			// TODO Auto-generated method stub
    			return Arrays.asList(new String[] { "szJobName", "szRevision", "nSide" });
    		}
    
    	}
    
    	public static class PRWBIF_HELPS_CHGOVERJOB extends Structure {
    
    		public static class ByReference extends PRWBIF_HELPS_CHGOVERJOB implements Structure.ByReference {
    		}
    		public static class ByValue extends PRWBIF_HELPS_CHGOVERJOB implements Structure.ByValue {
    		}
    		public int nLane;
    
    		public RWBIF_JOBINFO_EX stJob;
    
    		@Override
    		protected List getFieldOrder() {
    			// TODO Auto-generated method stub
    			return Arrays.asList(new String[] { "nLane", "stJob" });
    		}
    
    	}
    
    	
    	int iSendBarcodeIdEx(String szSrv, String szLine, String szEquip, int nJobChgMode, int nQty, int nSize,
    			RWBIF_PANELIDINFO_EX[] pArg);
    
    	int iGetRecipeChgProgress(String szSrv, String szLine, String szEquip, IntByReference rdwStatus);
    
    	int iGetAutoJobChgEquipQty(IntByReference rnQty, String szSrv, String szLine, String szEquip);
    
    	void iDelGetAutoJobChgResult();
    
    	
    	int iGetAutoJobChgResult(RWBIF_AUTO_JOB_CHG_RESULT.ByReference[] rval);
    
    	int iChangeOverJob(String szSrv, String szLine, String szEquip, int nJobChgMode, int nQty, int nSize,
    			PRWBIF_HELPS_CHGOVERJOB[] pArg);
    
    	
    
    }
    
    
    JNA  :
    public class NxtManager {
    
    	public static String DEFAULT_NXT_PROPERTIES = "nxt.properties";
    
    	private static String programName;
    
    	private static String m_strRWBSeverPC;
    
    	private static String m_strLine;
    
    	private static String m_strEquip;
    
    	private static String barcodeID;
    
    	private static String lane;
    
    	private static String szJobName;
    
    	private static String version;
    
    	private static String nSide;
    
    	private static String encode;
    
    	static {
    		InputStream inputStream = Thread.currentThread().getContextClassLoader()
    				.getResourceAsStream(DEFAULT_NXT_PROPERTIES);
    		Properties properties = new Properties();
    		try {
    			properties.load(inputStream);
    			programName = properties.getProperty("programName");
    			m_strRWBSeverPC = properties.getProperty("server");
    			m_strLine = properties.getProperty("lineName");
    			m_strEquip = properties.getProperty("equipName");
    			barcodeID = properties.getProperty("barcodeId");
    			lane = properties.getProperty("lane");
    			szJobName = properties.getProperty("jobName");
    			version = properties.getProperty("revision");
    			nSide = properties.getProperty("side");
    			encode = properties.getProperty("encode");
    			System.setProperty("jna.encoding", encode);
    
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			System.out.format("load nxt properties failed.");
    			e.printStackTrace();
    		}
    
    	}
    
    	public void onChangeoverJob() {
    		NxtService nxtServiceInstance = (NxtService) Native.loadLibrary(NxtManager.programName, NxtService.class);
    		int nDataQty = 1;
    		int nIndex = 1;
    		System.out.println("init---------->set value:");
    
    		System.out.println("nLane:" + Integer.valueOf(NxtManager.lane));
    		System.out.println("szJobName:" + NxtManager.szJobName);
    		System.out.println("szRevision:" + NxtManager.version);
    		System.out.println("nSide:" + Integer.valueOf(NxtManager.nSide));
    		
    		PRWBIF_HELPS_CHGOVERJOB[] prwbifHelpsChangeoverJob = (PRWBIF_HELPS_CHGOVERJOB[]) new NxtService.PRWBIF_HELPS_CHGOVERJOB()
    				.toArray(nDataQty);
    		prwbifHelpsChangeoverJob[0].nLane = Integer.valueOf(NxtManager.lane);
    		
    		RWBIF_JOBINFO_EX.ByValue stJobRef = new RWBIF_JOBINFO_EX.ByValue();
    
    		
    		stJobRef.nSide = Integer.valueOf(NxtManager.nSide);
    		//          ,java        
    		System.arraycopy(NxtManager.szJobName.getBytes(), 0, stJobRef.szJobName, 0, NxtManager.szJobName.getBytes().length);
    		System.arraycopy(NxtManager.version.getBytes(), 0, stJobRef.szRevision, 0, NxtManager.version.getBytes().length);
    		prwbifHelpsChangeoverJob[0].stJob = stJobRef;
    	
    		System.out.println("init---------->set value:end");
    
    		int nJobChgMode = 1;
    		int nSize = 152;
    
    		System.out.println("iChangeOverJob---------->start");
    		int nRet = nxtServiceInstance.iChangeOverJob(NxtManager.m_strRWBSeverPC, NxtManager.m_strLine,
    				NxtManager.m_strEquip, nJobChgMode, nDataQty, nSize, prwbifHelpsChangeoverJob);
    		if (0 != nRet) {
    			System.out.format("API call [iChangeOverJob]: Error Code = %08x )", nRet);
    			return;
    		}
    		System.out.println("iChangeOverJob---------->end");
    
    		try {
    			System.out.format("  7s");
    			Thread.sleep(TimeUnit.SECONDS.toMillis(7));
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    			return;
    		}
    
    		while (true) {
    			IntByReference dwStatus = new IntByReference(0);
    			System.out.println("iGetRecipeChgProgress---------->LOOP");
    			nRet = nxtServiceInstance.iGetRecipeChgProgress(NxtManager.m_strRWBSeverPC, NxtManager.m_strLine,
    					NxtManager.m_strEquip, dwStatus);
    			if (0 != nRet) {
    				System.out.format("API call [iGetRecipeChgProgress]: Error Code = %08x )", nRet);
    				return;
    			}
    			int dwStatusValue = dwStatus.getValue();
    			if (2 == dwStatusValue) {
    				break;
    			}
    			try {
    				System.out.format("  7s ,     complete(2)");
    				Thread.sleep(TimeUnit.SECONDS.toMillis(7));
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    				return;
    			}
    
    		}
    		System.out.println("iGetRecipeChgProgress---------->end,LOOP");
    
    		IntByReference rnQty = new IntByReference(0);
    
    		System.out.println("iGetAutoJobChgEquipQty---------->start");
    		nRet = nxtServiceInstance.iGetAutoJobChgEquipQty(rnQty, NxtManager.m_strRWBSeverPC, NxtManager.m_strLine,
    				NxtManager.m_strEquip);
    
    		if (0 != nRet) {
    			nxtServiceInstance.iDelGetAutoJobChgResult();
    		}
    		System.out.println("iGetAutoJobChgEquipQty---------->end");
    
    		int rnQtyValue = rnQty.getValue();
    		if (0 >= rnQtyValue) {
    			nxtServiceInstance.iDelGetAutoJobChgResult();
    			System.out.format("Error : Change over Result.(1)");
    			return;
    		}
    		RWBIF_AUTO_JOB_CHG_RESULT.ByReference[] pResult =  (ByReference[]) new NxtService.RWBIF_AUTO_JOB_CHG_RESULT.ByReference()
    				.toArray(rnQtyValue);
    
    		System.out.println("iGetAutoJobChgResult---------->start");
    		nRet = nxtServiceInstance.iGetAutoJobChgResult(pResult);
    		if (0 != nRet) {
    			nxtServiceInstance.iDelGetAutoJobChgResult();
    			System.out.format("API call [iGetAutoJobChgEquipQty]: Error Code = %08x )", nRet);
    			return;
    		}
    		System.out.println("iGetAutoJobChgResult---------->end");
    
    		boolean bResultOK = false;
    		for (int i = 0; i < rnQtyValue; i++) {
    
    			System.out.println("iDelGetAutoJobChgResult---------->Loop");
    			String szMcNameStr = new String(pResult[i].szMcName);
    			if (NxtManager.m_strEquip.trim().equals(szMcNameStr.trim())) {
    				if (0 != pResult[i].dwErrorCode) {
    					nxtServiceInstance.iDelGetAutoJobChgResult();
    					System.out.format("Error Code = %08x" + pResult[i].dwErrorCode);
    					return;
    				}
    				bResultOK = true;
    				break;
    			}
    
    		}
    		System.out.println("iDelGetAutoJobChgResult---------->Loop end");
    		if (false == bResultOK) {
    			nxtServiceInstance.iDelGetAutoJobChgResult();
    			System.out.format("Error : Change over Result.(2)");
    			return;
    		}
    		nxtServiceInstance.iDelGetAutoJobChgResult();
    		System.out.format("Change over from job complete.");
    		return;
    	}
    
    	/*
    	 * public static void main(String[] args) { NxtManager nxtManager = new
    	 * NxtManager(); nxtManager.onChangeoverJob(); }
    	 */
    
    	public void OnChangeoverId() throws UnsupportedEncodingException  {
    		System.out.println(System.getProperty("jna.encoding"));
    		NxtService nxtServiceInstance = (NxtService) Native.loadLibrary(NxtManager.programName, NxtService.class);
    		// String m_strRWBSeverPC = "10.187.0.54";
    		// String m_strLine = "H12";
    		// String m_strEquip = "NXT-H12";
    		int nJobChgMode = 1;
    		int nIndex = 1;
    
    		int nDataQty = 1;
    		int nSize = 140;
    		// set lane and barcode id
    		RWBIF_PANELIDINFO_EX[] pArg = (RWBIF_PANELIDINFO_EX[]) new NxtService.RWBIF_PANELIDINFO_EX().toArray(1);
    		pArg[0].szBarcode = NxtManager.barcodeID.getBytes();
    		pArg[0].nLane = Integer.valueOf(NxtManager.lane);
    
    		System.out.println("SendBarcodeId---------->start");
    
    		int nRet = nxtServiceInstance.iSendBarcodeIdEx(NxtManager.m_strRWBSeverPC, NxtManager.m_strLine,
    				NxtManager.m_strEquip, nJobChgMode, nDataQty, nSize, pArg);
    		if (0 != nRet) {
    			System.out.format("API call [iSendBarcodeIdEx]: Error Code = %08x )", nRet);
    			return;
    		}
    		System.out.println("SendBarcodeId---------->success");
    		try {
    			System.out.format("  7s ,     complete(2)");
    			Thread.sleep(TimeUnit.SECONDS.toMillis(7));
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    			return;
    		}
    		while (true) {
    			IntByReference dwStatus = new IntByReference(0);
    			System.out.println("GetRecipeChgProgress---------->Loop");
    			nRet = nxtServiceInstance.iGetRecipeChgProgress(NxtManager.m_strRWBSeverPC, NxtManager.m_strLine,
    					NxtManager.m_strEquip, dwStatus);
    			if (0 != nRet) {
    				System.out.format("API call [iGetRecipeChgProgress]: Error Code = %08x )", nRet);
    				return;
    			}
    			int dwStatusValue = dwStatus.getValue();
    			if (2 == dwStatusValue) {
    				break;
    			}
    			try {
    				System.out.format("  7s ,     complete(2)");
    				Thread.sleep(TimeUnit.SECONDS.toMillis(7));
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    				return;
    			}
    
    		}
    		System.out.println("GetRecipeChgProgress---------->loop end");
    		IntByReference rnQty = new IntByReference(0);
    
    		System.out.println("GetAutoJobChgEquipQty---------->start");
    		nRet = nxtServiceInstance.iGetAutoJobChgEquipQty(rnQty, NxtManager.m_strRWBSeverPC, NxtManager.m_strLine,
    				NxtManager.m_strEquip);
    		if (0 != nRet) {
    			System.out.format("API call [iGetAutoJobChgEquipQty]: Error Code = %08x )", nRet);
    			return;
    		}
    
    		System.out.println("GetAutoJobChgEquipQty---------->end");
    		// RWBIF_AUTO_JOB_CHG_RESULT rval = new
    		// NxtService.RWBIF_AUTO_JOB_CHG_RESULT();
    		int size = rnQty.getValue();
    		System.out.println("------------DEBUG------------->size" + size);
    		if (0 >= size) {
    			nxtServiceInstance.iDelGetAutoJobChgResult();
    			System.out.format("Error : Change over Result.(1)");
    			return;
    		}
    		
    //		RWBIF_AUTO_JOB_CHG_RESULT.ByValue[] rval = (ByValue[]) new NxtService.RWBIF_AUTO_JOB_CHG_RESULT.ByValue().toArray(size);
    		RWBIF_AUTO_JOB_CHG_RESULT.ByReference[] rval = (ByReference[]) new NxtService.RWBIF_AUTO_JOB_CHG_RESULT.ByReference().toArray(size);
    		System.out.println("GetAutoJobChgResult---------->start");
    //		nRet = nxtServiceInstance.iGetAutoJobChgResult(rval);
    		nRet = nxtServiceInstance.iGetAutoJobChgResult(rval);
    		if (0 != nRet) {
    			System.out.format("API call [iGetAutoJobChgResult]: Error Code = %08x )", nRet);
    			return;
    		}
    		System.out.println("GetAutoJobChgResult---------->end");
    		boolean bResultOK = false;
    		for (int i = 0; i < size; i++) {
    			System.out.println("debug:current system encode:" + StringUtils.getEncoding(NxtManager.m_strEquip));
    			String szMcNameStr = new String(rval[i].szMcName,StringUtils.getEncoding(NxtManager.m_strEquip));
    			System.out.println("debug:szMcNameStr ----->" + szMcNameStr + ":" + szMcNameStr.length());
    			System.out.println("debug:m_strEquip ----->" + NxtManager.m_strEquip  + ":" + NxtManager.m_strEquip.length());
    			String tempStrEquip = new String(NxtManager.m_strEquip.getBytes(),StringUtils.getEncoding(NxtManager.m_strEquip));
    			if (NxtManager.m_strEquip.equals(tempStrEquip)) {
    				if (rval[i].dwErrorCode != 0) {
    					nxtServiceInstance.iDelGetAutoJobChgResult();
    					System.out.format("Error Code = %08x", rval[i].dwErrorCode);
    					return;
    				}
    				bResultOK = true;
    				System.out.println("debug:String equal:ok");
    				break;
    			}
    		}
    		if (false == bResultOK) {
    			nxtServiceInstance.iDelGetAutoJobChgResult();
    			System.out.format("Error : Change over Result.(2)");
    			return;
    		}
    		System.out.println("success");
    		nxtServiceInstance.iDelGetAutoJobChgResult();
    		System.out.format("Change over from barcode ID complete.");
    	}
    
    	public static void main(String[] args) {
    
    		if (args.length < 1 || args.length > 2) {
    			System.out.println("      ");
    			return;
    		}
    		boolean isExit = false;
    		try {
    			int model = Integer.valueOf(args[0]);
    			NxtManager nxtManager = new NxtManager();
    			switch (model) {
    			case 0:
    				System.out.println("OnChangeoverId:  barcodeId    ");
    				nxtManager.OnChangeoverId();
    				break;
    			case 1:
    				System.out.println("onChangeoverJob:  jobName    ");
    				nxtManager.onChangeoverJob();
    				break;
    			default:
    				System.out.println("       ");
    				break;
    			}
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			System.out.println("        ");
    			e.printStackTrace();
    		}
    	}
    
    }
    
    

    좋은 웹페이지 즐겨찾기