java - 如何使用指向 Java 指针的指针填充结构?

标签 java jna

我正在尝试调用 C DLL 中的一个函数,该函数具有一个采用指向结构的指针的函数。该结构体(Data)的定义如下:

struct BD
{
    char* Data;
    int Length;
};

struct EE
{
    char* Key;
    BD* Value;
};

struct Data
{
    char* Name;
    BD* Picture;

    // A NULL-terminated array of pointers to EE structures.
    EE** Elements;
};

在 Java 中,我定义了一些如下所示的类:

public static class BD extends Structure implements Structure.ByReference {
    public byte[] Data;
    public int Length;
}

public static class EE extends Structure implements Structure.ByReference {
    public String Key;
    public BD Value;
}

public static class Data extends Structure {
    public String Name;
    public BD Picture;
    public PointerByReference Elements;
}

但现在我不知道如何正确填充 Data 对象。我想我可以找出 NamePicture 字段,但是我该如何设置 Elements 字段呢?我可以创建一个 EE 对象的 Java 数组,但是如何从中获取 PointerByReference 呢?也许我需要将 Elements 声明为 Pointer[] 但我只需使用 getPointer() 填充数组的每个元素即可每个EE对象?但这似乎不太正确?

编辑:为了更好地了解我正在尝试做什么:

Data data = new Data();
// Fill in Name and Picture fields.

EE[] elements = new Elements[10];
// Fill in the elements array.

// Now how do I set the Elements field on the data object from the elements array?
data.Elements = ???

Edit2:以下是我在 technomage 的帮助下解决该问题的方法:

我将我的Data结构更改为如下所示:

public static class Data extends Structure {
    public String Name;
    public BD Picture;
    public Pointer Elements;
}

我的 BD 结构如下所示:

public static class BD extends Structure implements Structure.ByReference {
    public Pointer Data;
    public int Length;
}

要将 Java byte[] 转换为 JNA Pointer,我必须使用 ByteBuffer:

ByteBuffer buf = ByteBuffer.allocateDirect(bytes.length);
buf.put(bytes);
bd.Data = Natvie.getDirectBufferPointer(buf);

不幸的是,JNA 不喜欢结构中的 ByteBuffer

为了获取我的元素指针,我需要创建一个指向每个 EE 对象的 Pointer 数组(请参阅 technomage 的关于 PointerArray 实现的答案):

EE e = new EE();
// Populate e object.
// ...

// Important: ensure that the contents of the objects are written out to native memory since JNA can't do this automatically
e.write();
ptrs.add(e);

// Once each object is setup we can simply take the array of pointers and use the PointerArray
data.Elements = new PointerArray(ptrs.toArray(new Pointer[0]));

我无法在结构定义中直接使用 ByteBufferPointerArray,因此我必须依赖 Pointer

最佳答案

Elements 设为 Pointer,然后使用 Pointer.getPointerArray(0) 检索感兴趣的结构指针。

然后,您需要从每个检索到的 Pointer 初始化每个 Structure(不要忘记调用 Structure.read()) .

没有办法自动执行指针上的间接寻址并最终得到一个 Structure 数组,但它很简单,可以编码到 Structure 上的方法中类(例如 Data.getElements())。

编辑

示例指针数组实现,在写入(而不是读取)时初始化指针数组:

class PointerArray extends Memory {                      
        private final Pointer[] original;                                                           
        public PointerArray(Pointer[] arg) {                                                        
            super(Pointer.SIZE * (arg.length+1));                                                   
            this.original = arg;                                                                    
            for (int i=0;i < arg.length;i++) {                                                      
                setPointer(i*Pointer.SIZE, arg[i]);                                                 
            }                                                                                       
            setPointer(Pointer.SIZE*arg.length, null);                                              
        }                                                                                           
    }
}

在调用 native 函数之前,您还需要调用 Structure.write()(您可以将其作为 PointerArray 的一部分执行此操作),因为 JNA 不这样做知道当您使用普通的 Pointer 而不是 Structure 时,内存需要同步。

关于java - 如何使用指向 Java 指针的指针填充结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17556456/

相关文章:

java - 如何使用 JPA GenerationType.AUTO 提供初始值或增量 ID

java - 我们如何修复这个错误? java.lang.IllegalStateException

java - Java中使用ehcache RMI的分布式缓存

java - 没有 Hibernate session 绑定(bind)到带有 generic-hibernate-dao 库的线程

java - 如何获取用于在 Mac 上创建火焰图的 Java 分析转储?

java - JNA 对象在 java 代码中是按引用传递还是按值传递

java - 使用 jna 加载 lib.so

java - JNA、映射和指针引用

java - 获取当前可见窗口标题的 Null 值

c - 尝试在 Visual Studio 中制作 Java Native Access 将接受的 "Hello Word"dll