參考文章《JNA:JAVA調(diào)用DLL 超詳細(xì)代碼實戰(zhàn)》和《JNA?Examples》實現(xiàn)了java和c實現(xiàn)的dll相互調(diào)用,細(xì)節(jié)如下:
1、dll生成
我們繼續(xù)使用《Golang與DLL交互》一樣的c代碼
使用vs2013生成dll庫,添加代碼如下:
// testdll.cpp : 定義 DLL 應(yīng)用程序的導(dǎo)出函數(shù)。
//
#include "stdafx.h"
#include <stdio.h>
#ifndef TM_ROBOT_API
#define TM_ROBOT_API extern "C" __declspec(dllexport)
#else
#define TM_ROBOT_API extern "C" __declspec(dllimport)
#endif
TM_ROBOT_API void fun1(int* pVal) {
char buff[128];
sprintf_s(buff, "fun1, val: %d -> 999\n", *pVal);
OutputDebugStringA(buff);
*pVal = 999;
}
struct MyStruct
{
int nVal1;
float nVal2;
};
typedef int(*CB_MY)(int nVal, int fVal);
TM_ROBOT_API void fun2(MyStruct* pVal) {
char buff[128];
sprintf_s(buff, "fun2, val: 1->%d, 2->%.4f -> 1,2\n", pVal->nVal1, pVal->nVal2);
OutputDebugStringA(buff);
pVal->nVal1 = 1;
pVal->nVal2 = 2.2;
}
TM_ROBOT_API void fun3(CB_MY pFun) {
char buff[128];
sprintf_s(buff, "fun3, val: %08X -> call it 10s\n", pFun);
OutputDebugStringA(buff);
for (int i = 80; i<100; i++)
{
pFun((int)(i*3.3), (int)(i*1.1));
Sleep(10);
}
}
特別注意的是系統(tǒng)64為要生成64位的dll
2、java代碼--jna接口,HelloInterface.java
package com.test.hellojna;
import java.util.Arrays;
import java.util.List;
import com.sun.jna.Callback;
import com.sun.jna.Library;
import com.sun.jna.Structure;
import com.sun.jna.ptr.IntByReference;
public interface HelloInterface extends Library {
public void fun1(IntByReference? pVal);
public void fun2(MyStruct.ByReference pVal);
public void fun3(CB_MY pFun);
// define an interface that wraps the callback code
public interface CB_MY extends Callback {
int invoke(int nVal,int fVal);
}
public static class MyStruct extends Structure {
public static class ByReference extends MyStruct implements Structure.ByReference {
}
public int nVal1;
public float nVal2;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] { "nVal1", "nVal2" });
}
}
}
這里注意的是指針的地方都是對應(yīng)相應(yīng)的Reference類
結(jié)構(gòu)體的特殊定義和回調(diào)函數(shù)的特殊定義
3、java代碼-dll接口實例,HelloBase.java
package com.test.hellojna;
import com.sun.jna.Native;
public class HelloBase {
public static HelloInterface instance = null;
public static HelloInterface getInstance() {
if (instance != null)
return instance;
try {
instance = (HelloInterface)Native.loadLibrary("testdll", HelloInterface.class);
} catch (Exception e) {
e.printStackTrace();
}
return instance;
}
}
4、java代碼--測試代碼,App.java
package com.test.hellojna;
import com.sun.jna.ptr.IntByReference;
import com.test.hellojna.HelloInterface.CB_MY;
/**
* Hello world!
*
*/
public class App
{
? ? public static void main( String[] args )
? ? {
? ? HelloInterface myinterface = HelloBase.getInstance();
? ? int aa = 10;
? ? final IntByReference aa_valRef = new IntByReference(aa);
? ? myinterface.fun1(aa_valRef);
? ? System.out.println("########" + aa_valRef.getValue());
? ? final HelloInterface.MyStruct.ByReference arg1 = new HelloInterface.MyStruct.ByReference();
? ? arg1.nVal1 = 11;
? ? arg1.nVal2 = 22.22f;
? ? myinterface.fun2(arg1);
? ? System.out.println("************" + "nVal1=" + arg1.nVal1 + ",nVal2=" + arg1.nVal2);
? ? myinterface.fun3(new CB_MY() {
? ? public int invoke(int nVal,int fVal) {
? ? ? ? System.out.println("cb_my:" + nVal+ " " + fVal);
? ? ? ? return 0;
? ? }
? ? }) ;
? ? System.out.println("============");
? ? }
}
這里要注意的是Reference相關(guān)的都需要new
具體工程代碼放在csdn:
c代碼:https://download.csdn.net/download/oracle2488/10815527
java代碼:https://download.csdn.net/download/oracle2488/10815819