1

我试图在 C DLL 中调用一个函数,该函数具有一个函数,该函数接受一个指向结构的指针。这个 struct ( 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正确填充对象。我想我可以弄清楚NameandPicture字段,但是我将Elements字段设置为什么?我可以创建一个 JavaEE对象数组,但是如何从中获取 PointerByReference 呢?也许我需要声明Elements为 aPointer[]但是我是否只需用getPointer()for 每个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结构中的 s。

为了获得我的元素指针,我需要为Pointer每个EE对象创建一个 s 数组(参见 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]));

我不能使用ByteBufferorPointerArray直接在结构定义中,所以我不得不依赖Pointer.

4

1 回答 1

2

制作Elements一个Pointer,然后使用它Pointer.getPointerArray(0)来检索感兴趣的结构指针。

然后,您需要Structure从每个检索到的中初始化每个Pointer(不要忘记调用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);                                              
        }                                                                                           
    }
}

您还需要Structure.write()在调用本机函数之前调用(您可以将PointerArrayPointer作为Structure.

于 2013-07-09T21:22:05.260 回答