使用JNA机制实现HelloWorld和简单例子
JNA框架是一个开源的Java框架,是建立在经典的JNI基础之上的一个框架。
JNA使用一个小型的JNI库插桩程序来动态调用本地代码。
JNA是建立在JNI技术基础之上的一个Java类库,它使您可以方便地使用java直接访问动态链接库中的函数。
原来使用JNI,你必须手工用C写一个动态链接库,在C语言中映射Java的数据类型。
JNA中,它提供了一个动态的C语言编写的转发器,可以自动实现Java和C的数据类型映射,不再需要编写C动态链接库。
在Idea中使用JNA:
- 获取到JNA.jar
GitHub - java-native-access/jna: Java Native Access
- 在Idea创建Java项目,导入JAR包
Idea: File → Project Structure → Libraries → “+”
将下载的jna.jar 加入到项目中
- 在项目src文件夹下,新建Test.java:
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
public class Test {
// This is the standard, stable way of mapping, which supports extensive
// customization and mapping of Java to native types.
public interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary)
Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"),
CLibrary.class);
void printf(String format, Object... args);
}
public static void main(String[] args) {
int j = 1 ;
CLibrary.INSTANCE.printf("Hello,%d World\n",j);
for (int i=0;i < args.length;i++) {
CLibrary.INSTANCE.printf("Argument %d: %s\n", i, args[i]);
}
}
}
- 直接运行:
JNA Example:
使用Example
Example入门:Example #1: Send and Receive an Integer
- 新建example.c文件:
int example1(int val)
{
return val * 2;
}
- 在当前文件夹下终端运行:
gcc -dynamiclib -o libtestlib.dylib example.c
生成Java调用需要的动态链接库
- 新建Integer类文件:
import com.sun.jna.Library;
import com.sun.jna.Native;
public class Integer {
public interface CLibrary extends Library {
public int example1(int val);
}
public static void main(String[] args) {
final CLibrary clib = (CLibrary) Native.loadLibrary("libtestlib", CLibrary.class);
int newVal = clib.example1(23);
System.out.println("example 1: " + newVal);
}
}
- 运行
过程中出现的问题:
运行出现Native library (darwin-aarch64/liblibtestlib.dylib) not found in resource path
问题
-
解决:
将Native.loadLibrary()方法中的name 更改为绝对路径(将“libtestlib” 更换为此文件的绝对路径),即可运行
Java调用C Struct 结构体出现的问题:
运行出现Structure.getFieldOrder() on class Send_Struct.Test_S_S$CLibrary$Example3Struct$ByReference returns names ([]) which do not match declared field names ([value])
此类ByReference问题,在jna 5.x中,需要加@FieldOrder()注解
如在Example #3中:
@Structure.FieldOrder({"value"})
class Example3Struct extends Structure {
public static class ByReference extends Example3Struct implements Structure.ByReference {}
public int value;
}
便可运行。
Ref:
https://www.cnblogs.com/lanxuezaipiao/p/3635556.html
https://stackoverflow.nilmap.com/question?dest_url=https://stackoverflow.com/questions/64835834/jna-structure-getfieldorder-does-not-match-declared-field-names
https://www.saoniuhuo.com/question/detail-2074103.html