JAVA与DLL交互

jna官网地址:https://jna.dev.java.net/

首先写了一个用于测试的DLL文件:

FirstDLL.h头文件:

 

#ifdef FirstDLL_API
#else
#define 
FirstDLL_API extern "C" _declspec(dllimport)
#endif

typedef struct{
	char* userName;
	int age;
	char* tel;
}User;

FirstDLL_API int GetSum(int a,int b);
FirstDLL_API char* CallChar(char* a);
FirstDLL_API void CallPointer(int *a);
FirstDLL_API void CallPIntArray(int *a,int len);
FirstDLL_API int CallStruct(User &user);
FirstDLL_API int CallStructArray(User *user,int len);
FirstDLL_API void CallVRef(int a,int b,int &c);


 FirstDLL.cpp文件:

#define FirstDLL_API extern "C" _declspec(dllexport)
#include "FirstDLL.h"
#include <iostream.h>


int GetSum(int a,int b)
{
	return a+b;
}

char* CallChar(char* a){
	return a;
}

int CallStruct(User &user){
	user.userName = "陈均";
	user.age = 22;
	user.tel = "8888888";
	return 0;
}

int CallStructArray(User *user,int len){
	for(int i = 0;i<len;i++)
	{
		user->userName = "陈均";
		user->age = i+1;
		user->tel = "电话";
		user++;
	}
	return 0;
}


void CallPointer(int *a){
	*a = 5;
}

void CallPIntArray(int *a,int len){
	for(int i = 0;i<len;i++){
		*a = i+3;
		a++;
	}
}


void CallVRef(int a,int b,int &c){
	c = a + b;
}

 

编译后生成FirstDLL.dll文件.

测试文件FirstDLLTest:如果是Delphi写的DLL,将下面的生命改成如下格式即可

typedef int (FAR PASCAL *SetSrvProc)(int srv,int zh,int jh);

#include <iostream.h>
#include <WINDOWS.H>
#include <WINBASE.H>

HINSTANCE first_dll = NULL;

//声明结构体类型
typedef struct{
	char* userName;
	int age;
	char* tel;
}User;

//外部dll声明
typedef int (*GetSumProc)(int a,int b);
typedef int (*CallStructProc)(User &user);
typedef int (*CallStructArrayProc)(User *user,int len);
typedef void (*CallPointerProc)(int *a);
typedef void (*CallPIntArrayProc)(int *a,int len);
typedef void (*callVRefProc)(int a,int b,int &c);

//结构体声明
typedef struct{
	int kh;//0x0000,0x0001,0x0002,0x0003
	unsigned char mu;//0x0004
	short qty;// 0x0006,0x0007
	int je;// 0x0008,0x0009,0x000A,0x000B
	int ye;// 0x000C,0x000D,0x000E,0x000F
	unsigned short year;//0x0010,0x0011
	unsigned char month,day,hour,minute,second,ms,sd;//0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018
	unsigned char jh;//0x0019
	unsigned char lb;//0x001A
	unsigned char online;//0x001B
	//如果对齐设置默认8则:0x0000-0x001B共28个字节-->4倍  28
	//如果对齐设置1则:0x0000-0x001A共27个字符
}PKQRCDA;


void main()
{
	
	User user;
	User array[2];

	//调用外部dll的GetSum方法
	first_dll = LoadLibrary("E:\\C++WORK\\FirstDLL\\Debug\\FirstDLL.dll");
	if(first_dll!=NULL){
		GetSumProc getSum = (GetSumProc)GetProcAddress(first_dll,"GetSum");
		int result = getSum(4,5);
		cout<<result<<endl;
		CallStructProc callStruct = (CallStructProc)GetProcAddress(first_dll,"CallStruct");
		result = callStruct(user);
		cout<<user.userName<<endl;
		CallStructArrayProc callStructArray = (CallStructArrayProc)GetProcAddress(first_dll,"CallStructArray");
		result = callStructArray(array,2);
		cout<<array[0].age<<endl;
		CallPointerProc callPointer = (CallPointerProc)GetProcAddress(first_dll,"CallPointer");
		int a = 3;
		callPointer(&a);
		cout<<a<<endl;
		CallPIntArrayProc calPIntArray = (CallPIntArrayProc)GetProcAddress(first_dll,"CallPIntArray");
		int len = 3;
		int pia[20];
		calPIntArray(pia,len);
		callVRefProc calVRef = (callVRefProc)GetProcAddress(first_dll,"CallVRef");
		int c;
		calVRef(4,7,c);
		

	}


}

 

以下是java测试:

IFirstDLL接口文件:

public interface IFirstDLL extends Library {
	//绝对路径,在开发的时候可以这样写,方便更新
	IFirstDLL INSTANCE = (IFirstDLL) Native.loadLibrary("E:\\C++WORK\\FirstDLL\\Debug\\FirstDLL.dll", IFirstDLL.class);
	//相对路径,在不修改dll的时候可放到jdk/bin下面或者system32
	//IFirstDLL INSTANCE = (IFirstDLL) Native.loadLibrary("FirstDLL", IFirstDLL.class);
	//下面是dll对应的接口方法声明,参数类型和返回类型要一致
	//结构体声明
	public static class User extends Structure{
		public String userName;
		public int age;
		public String tel;
	}
	
	//值传递
	int GetSum(int a,int b);
	//字符串传递
	String CallChar(String a);
	//整形指针传递
	void CallPointer(IntByReference a);
	//整形数组传递,c指针变量
	void CallPIntArray(int []a,int len);
	//结构体值传递
	public int CallStruct(User user);
	//结构体数组传递,结构体指针变量接收
	public int CallStructArray(User[] user,int len);
	//带返回值的传递
	public void CallVRef(int a,int b,IntByReference c);
	
}

 

测试文件IFirstDLLTest:

public class IFirstDLLTest {

	public static void main(String[] args) {
		IFirstDLL firstDLL = IFirstDLL.INSTANCE;
		int a = 4;
		int b = 6;
		firstDLL.GetSum(a, b);
		firstDLL.CallChar("字符串内容");
		IntByReference d = new IntByReference();
		firstDLL.CallPointer(d);
		int[] e = new int[2];
		firstDLL.CallPIntArray(e, e.length);
		User user = new User();
		firstDLL.CallStruct(user);
		System.out.println("userName:" + user.userName+";age=" + user.age + ";tel=" + user.tel);
		User[]users = new User[3];
		firstDLL.CallStructArray(users, users.length);
		IntByReference c = new IntByReference();
		firstDLL.CallVRef(3, 5, c);
	}
}

 

搞定了,常用的交互基本上都有了。复杂的也是这些演变出来的。

附件包含上面3个工程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值