Java使用JNA调用动态链接库

之前写过一篇Java使用JNI调用动态链接库,使用原生JNI调用C++,操作非常繁琐。需要现有C++服务层,JNI代理层,然后才是Java调用层。前几天突然在网上看到JNA的框架,发现非常好用。写个DEMO试试,也方便以后查找。

动态库开发

  • 头文件
1
2
3
4
5
6
7
8
9
#ifndef PERSON_PERSONJNA_H
#define PERSON_PERSONJNA_H
#include <iostream>

extern "C" __declspec(dllexport) void hello(char* name);

extern "C" __declspec(dllexport) int add(int a,int b);

#endif //PERSON_PERSONJNA_H
  • 源文件
1
2
3
4
5
6
7
8
9
10
#include "PersonJNA.h"
#include <iostream>

extern "C" __declspec(dllexport) void hello(char* name){
std::cout << "我的名字叫: "<<name<<std::endl;
}

extern "C" __declspec(dllexport) int add(int a,int b){
return a + b;
}
  • 编译脚本
1
2
3
4
5
cmake_minimum_required(VERSION 3.18)
project(person)
set(CMAKE_CXX_STANDARD 11)
add_library(person SHARED PersonJNA.cpp)

点击build既可生成文件libperson.dll,这个文件是windows下的动态链接库文件

如果需要打Linux下使用的SO文件,可以将代码放到linux下执行,Clion支持远程调试功能

1
2
3
4
5
sudo apt install g++ gcc gdb cmake
mkdir build
cd build
cmake ../
make

Java调用动态链接库

我们将上面生成的libperson.dll拷贝到项目中。然后在gradle中引入JNA依赖

1
2
implementation 'net.java.dev.jna:jna:5.11.0'
implementation 'net.java.dev.jna:jna-platform:5.11.0'

然后编写代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class JNAClass {

public interface JNALibrary extends Library {
JNALibrary INSTANCE = Native.load("D:\\Java\\spring-boot-demo\\src\\main\\resources\\libperson.dll",JNALibrary.class);

void hello(String name);

int add(int a,int b);
}

public void print(String name){
JNALibrary.INSTANCE.hello(name);
}

public int add(int a,int b){
return JNALibrary.INSTANCE.add(a,b);
}
}

编写Main函数调用

1
2
3
4
5
6
7
8
9
10
11
@Slf4j
public class JNAMain {

public static void main(String[] args) {
JNAClass jnaClass = new JNAClass();
jnaClass.print("张三");
jnaClass.print("李四");
jnaClass.print("王五");
log.info("计算结果为: {}",jnaClass.add(1,2));
}
}

调用结果如下

总结

本文在Java使用JNI调用动态链接库的基础上使用了JNA进行C++的调用,简化了开发过程。JNA还有很多的知识点,比如类型映射,函数回调,使用指针,数组,使用结构和联合等。等实际应用中再进行更新。

JNA项目地址: https://github.com/java-native-access/jna

作者

Labradors

发布于

2022-05-05

更新于

2022-05-06

许可协议

评论