java - 如何将指针传递给 JNA 中的结构?

标签 java jna

我正在研究一个示例,将指向结构的指针传递给 red hat Linux 平台中的 native 库。我遵循了给出的常见问题解答和说明 here .到目前为止没有任何结果。我的 native 代码如下所示:

typedef struct Code
{
    unsigned char a;
    unsigned char b;
    unsigned char c;
    unsigned char d;
    unsigned char e;
    unsigned char f;
} CODE;

void printStruct(CODE * code) {

    printf("OBIS value =%d.%d.%d.%d.%d.%d \n ", code->a, code->b, code->c, code->d, code->e, code->f);
    
}

我的 Java 代码如下:

public class JNATest {


    interface CLibrary extends Library {
        public static class CODE extends Structure {
            public int a=0,b=1,c=2,d=3,e=4,f=5;
            public CODE() {
                allocateMemory();
                autoWrite();
            }
            public CODE(Pointer p) {
                super(p);
            }
            @Override
            protected List getFieldOrder() {
                return Arrays.asList(new String[]{"a", "b",
                        "c", "d", "e", "f"});
            }
            
            public static class ByReference extends CODE implements Structure.ByReference {};
            public static class ByValue extends CODE implements Structure.ByValue {};
        }

        CLibrary INSTANCE = (CLibrary) Native.loadLibrary("./libStructTest.so", CLibrary.class);
        void sayHello(String name);
        void printStruct(CODE obis);
    }
    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            CLibrary.INSTANCE.sayHello("Sara");
            struct.JNATest.CLibrary.CODE obis = new struct.JNATest.CLibrary.CODE();
            obis.writeField("a", 0);
            obis.writeField("b", 0);
            obis.writeField("c", 1);
            obis.writeField("d", 0);
            obis.writeField("e", 0);
            obis.writeField("f", 255);
            obis.write();
            
            Pointer ptr = obis.getPointer();
            System.out.println("ptr = " + ptr.toString());
            CLibrary.INSTANCE.printStruct(obis);
            Pointer p = obis.getPointer();                              
            System.out.println(obis.size() + ":c=" + obis.c);  

            System.out.println(obis.size() + ":c=" + obis.c);
            
        } catch (UnsatisfiedLinkError e) {
            System.out.println("Exception" + e);
        }
    }
}

当我尝试 java 程序时,我没有在结构成员变量 a、b、c、d、e、f 中获取传递的值,但始终为 0。

ptr = auto-allocated@0x6d3daa68 (24 bytes)
OBIS value =0.0.0.0.0.0
24:c=1
24:c=1

我是否遗漏了 Java 代码中的某些内容?任何帮助是极大的赞赏。 提前致谢。

最佳答案

我以前使用过下面的模式,因为我发现它的性能高于 JNA 执行的自动编码(marshal)处理。试一试。

一、结构:

public class Code {
   private Pointer pointer;

   Code() {
      long memory = Native.malloc(6);
      pointer = new Pointer(memory);
   }

   void free() {
      Native.free(Pointer.nativeValue(pointer));
   }

   Pointer getPointer() {
      return pointer;
   }

   byte getA() {
      return pointer.getByte(0);
   }

   byte getB() {
      return pointer.getByte(1);
   }

   byte getC() {
      return pointer.getByte(2);
   }
   ...

   void setA(byte a) {
      pointer.setByte(0, a);
   }

   void setB(byte b) {
      pointer.setByte(1, b);
   }

   void setC(byte c) {
      pointer.setByte(2, c);
   }
   ...
}

接下来,API:

class JNATest {
   static {
      Native.register("StructTest"); // undecorated name ... becomes libStructTest.so on Linux
   }

   public static native void printStruct(Pointer obis);
}

最后是用法:

Code code = new Code();
code.setA((byte) 'a');
code.setB((byte) 'b');
...
JNATest.printStruct(code.getPointer());
code.free();  // free the memory allocated in the constructor

如果你有不同的结构,如 shortintlong 等,Pointer 类提供读取/写入它们的简单访问器。

关于java - 如何将指针传递给 JNA 中的结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20512788/

相关文章:

java - 将整数存储在数组中后打印文件中的整数数量?

java - 如何在Java中加载和使用第三方.dll的功能

java - 在 Node 中加载 Java JNA 原生库

java - Primefaces p :fileDownload with datatable

java - 收集对象数组的属性列表

java - 未在 Android Dagger 项目中注入(inject)字段

java - 使用 JNA 调用另一个进程中的函数

java - 将方法转换为对象以通过 HTTP 发送

java - 库 'jna-4.2.2.jar' 包含不会在 Android 设备上运行的 native 库

java - 如何使用 JNA 访问 Mac OS X 内核框架 (mach)