通过jnr 进行native 库的调用

jnr 是一个java外部native 库使用的抽象层,可以让我们直接调用native 模块,目前jnr 提供了完整的类型映射以及内存管理能力,使用上实际与jna 基本类似,值得尝试下

easytier-ffi jnr 参考使用

  • 定义

public class EasyTierLibraryV2
{
    public static class  KeyValuePair extends Struct {
        public final Pointer key = new Pointer();
        public final Pointer value = new Pointer();

        public KeyValuePair(jnr.ffi.Runtime runtime) {
            super(runtime);
        }
    }
    public interface EasyTier { // A representation of libC in Java
        void get_error_msg(Pointer out);
        void free_string(Pointer s);
        int parse_config(String cfg_str);
        int run_network_instance(String cfg_str);
        int retain_network_instance(String inst_names, long length);
        int collect_network_infos(Pointer infos, long max_length);
    }
}

  • 调用
EasyTierLibraryV2.EasyTier lib = LibraryLoader.create(EasyTierLibraryV2.EasyTier.class)
        .search("<path>")
        .load("easytier_ffi");
var config  = Files.readString(Path.of("app.yaml"));
var result = lib.run_network_instance(config);
if(result == 0) {
    System.out.println("Network instance started successfully.");
    while (true) {
        try {
            Thread.sleep(3000);
            int MAX_LENGTH = 10;
            Runtime runtime = Runtime.getSystemRuntime();
            EasyTierLibraryV2.KeyValuePair[] infos = new EasyTierLibraryV2.KeyValuePair[MAX_LENGTH];
            Pointer buffer = Memory.allocate(runtime, MAX_LENGTH * Struct.size(new EasyTierLibraryV2.KeyValuePair(runtime)));
            for (int i = 0; i < MAX_LENGTH; i++) {
                infos[i] = new EasyTierLibraryV2.KeyValuePair(runtime);
                infos[i].useMemory(buffer.slice(i * Struct.size(infos[i])));
            }
            int count = lib.collect_network_infos(buffer, MAX_LENGTH);
            System.out.println("Collected " + count + " network infos:");
            for (int i = 0; i < count; i++) {
                String key = infos[i].key.get().getString(0);
                String val = infos[i].value.get().getString(0);
                lib.free_string(infos[i].value.get());
                lib.free_string(infos[i].key.get());
                System.out.println(key + ": " + val);
            }
        } catch (InterruptedException e) {
            System.out.println("Application interrupted: " + e.getMessage());
            break; // Exit the loop if interrupted
        }
    }
}

参考资料

https://github.com/jnr/jnr-ffi

https://github.com/jnr/jnr-ffi/tree/master/docs

https://github.com/jnr/jnr-ffi/blob/master/docs/WhyUseJNR.md

https://github.com/jnr/jnr-ffi/blob/master/docs/GettingStarted.md

posted on 2025-08-21 08:39  荣锋亮  阅读(11)  评论(0)    收藏  举报

导航