之前开发的项目里需要用到一种电子设备,而电子设备的操作接口是用C语言开发,而我们的项目是用Java进行开发,所以就涉及到了Java调用C语言Dll库回调函数问题,在网上找了很多资料,但是真正好用的很少,反复测试最终把这个问题得以解决。
今天有时间就把这些整理一下,希望可以帮到以后遇到此类问题的猿猿们。
使用Java调用DLL动态链接库的方案有很多,如:JNA、JNI、Jawin、Jacob等,而此次用到的是JNA,关于JNA的简介可以参考百度百科,这里就不再多说。
这里首先看一下C语言库的源代码,sa.h:这里定义了一个带回调函数的方法和一个普通方法
#ifndef _SA_H
#define _SA_H
#ifdef API_EXPORT
#define API_DLL _declspec(dllexport)
#else
#define API_DLL _declspec(dllimport)
#endif
typedef void (__stdcall *CALLBACK_FUN)(int x);
extern "C" API_DLL void printfValue(CALLBACK_FUN f);
extern "C" API_DLL int Calc(int xa);
#endif
sa.app源代码如下:
#include "stdafx.h"
#define API
#include "sa.h"
CALLBACK_FUN fun;
int x = 200;
char str[] = "abcd";
void printfValue(CALLBACK_FUN f)
{
fun = f;
fun(x);
}
int Calc(int xa)
{
x = xa;
return x;
}
Java源代码如下:
import com.sun.jna.Native;
import com.sun.jna.win32.StdCallLibrary;
public class SaDllCallbackFunctionTest {
DllLib1 cf = null;
public boolean init() {
try {
cf = (DllLib1) Native.loadLibrary("sa.dll",DllLib1.class);
if (cf != null)
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public static void main(String[] arg0){
SaDllCallbackFunctionTest ope = new SaDllCallbackFunctionTest();
if(ope.init()){
System.out.println(ope.cf.Calc(200));;
DllLib1.CallbackFunctionImpl FUN_CMC = new DllLib1.CallbackFunctionImpl();
ope.cf.printfValue(FUN_CMC);
}
}
}
interface DllLib1 extends StdCallLibrary {
public int Calc(int x);
public void printfValue(CallbackFunctionImpl FUN_CMC);
public interface CallbackFunction extends StdCallCallback {
public void CALLBACK_FUN(int a);
}
public class CallbackFunctionImpl implements CallbackFunction {
public void CALLBACK_FUN(int a) {
System.out.println("========" + a);
}
}
}