熟悉JNA机制-实现Java调用C:HelloWorld和简单例子

使用JNA机制实现HelloWorld和简单例子

JNA框架是一个开源的Java框架,是建立在经典的JNI基础之上的一个框架。
JNA使用一个小型的JNI库插桩程序来动态调用本地代码。
JNA是建立在JNI技术基础之上的一个Java类库,它使您可以方便地使用java直接访问动态链接库中的函数。
原来使用JNI,你必须手工用C写一个动态链接库,在C语言中映射Java的数据类型。
JNA中,它提供了一个动态的C语言编写的转发器,可以自动实现Java和C的数据类型映射,不再需要编写C动态链接库。

在Idea中使用JNA:

  1. 获取到JNA.jar

GitHub - java-native-access/jna: Java Native Access

  1. 在Idea创建Java项目,导入JAR包
    Idea: File → Project Structure → Libraries → “+”
    将下载的jna.jar 加入到项目中

添加Jar包

  1. 在项目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]);
        }
    }
}
  1. 直接运行:

HelloWorld

JNA Example:

JNA Examples

使用Example

Example入门:Example #1: Send and Receive an Integer

  1. 新建example.c文件:
int example1(int val)
{
    return val * 2;
}
  1. 在当前文件夹下终端运行:
gcc -dynamiclib -o libtestlib.dylib example.c

生成Java调用需要的动态链接库

  1. 新建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);
    }
}
  1. 运行

Example #1

过程中出现的问题:

运行出现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


Blog

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值