之前写过一篇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
|
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