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个工程。