如何使用二维指针通过 JNA 调用 C 函数?

How to call C function through JNA with 2d pointer?

这是我的 C 函数的签名:

typedef struct myitem_s {
    int a;
    int b;
} myitem_t;

int get_items(myitem_t** items);

在C程序中的用法是::

myitem_t* items = NULL;
int n = = get_items(&items);

for (int i = 0; i < n; ++i) {
    myitem_t* item = &items[i];
}

items分配在get_items()函数中,包含一个或多个myitem_t个元素。

从 Java 代码我已经成功地做到了这一点:

Memory itemsPtr = new Memory(Native.POINTER_SIZE);
Pointer p = itemsPtr.getPointer(0);
int n = CLibrary.INSTANCE.get_items(p);

n 值有效,itemsPtr 已更新,所以我建议值也不错。现在我不知道如何使用它。还有其他方法吗?

您的代码有效,但是当 JNA 具有一些更高级别的构造时,您使用了很多较低级别的函数。

首先,Cstruct可以用JNAStructure表示。

@FieldOrder({ "a", "b" })
class MyitemT extends Structure {
    public int a;
    public int b;
}

由于本机代码正在处理内存分配,您所需要的只是指向它的指针。您可能需要 PointerByReference.

而不是 pointer-sized 内存分配
PointerByReference pbr = new PointerByReference();

你想要的关键方法是getPointer()(指向指针的指针)和getValue()(pointed-to值)。

鉴于上述情况,将 pointer-to-the-pointer 传递给方法,该方法将分配内存并填充值。

使用您已有的映射(未显示但推断):

int n = CLibrary.INSTANCE.get_items(pbr.getPointer());

但是,您实际上应该映射 get_items() 以获取 PointerByReference 参数,然后您可以直接传递 items

此时,items.getValue() 是结构数组开头的 Pointer。根据结构的大小 (item.size()),其他项目将位于指针值的偏移量处。有多种方法可以做到这一点。

在你的情况下,因为你知道你只有一对整数,你可以跳过整个“结构”部分,只使用 items.getValue().getInt(0)items.getValue().getInt(4) 作为第一对;第二对是 8 和 12,等等。但更好的是,只需 items.getValue().getIntArray(0,n*2); 获取一个整数数组,只需将它们成对取出即可。

但这利用了内部细节。最 JNA-ish 的选择可能是使用 Structure.toArray() 创建一个 MyitemT 结构数组。如果包含指针构造函数并使用该指针创建初始结构,Structure.toArray() 将使用该现有映射。然后你可以 read() 进入你的数组:

MyItemT item = new MyItemT(pbr.getValue());
MyItemT[] items = (MyItemT[]) item.toArray(n);
for (int i = 0; i < n; i++) { 
    items[i].read();
    // now you can see items[i].a and items[i].b
}

不要忘记最终释放 native-allocated 内存,但是 API 告诉你这样做!