参考文章《JNA:JAVA调用DLL 超详细代码实战》和《JNA Examples》实现了java和c实现的dll相互调用,细节如下:
1、dll生成
我们继续使用《Golang与DLL交互》一样的c代码
使用vs2013生成dll库,添加代码如下:
// testdll.cpp : 定义 DLL 应用程序的导出函数。
//
#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);
}
}
特别注意的是系统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" });
}
}
}
这里注意的是指针的地方都是对应相应的Reference类
结构体的特殊定义和回调函数的特殊定义
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相关的都需要new
具体工程代码放在csdn:
c代码:https://download.csdn.net/download/oracle2488/10815527
java代码:https://download.csdn.net/download/oracle2488/10815819