JNA 传递结构,包含指向结构的指针和指向基元的指针

我正在使用 JNA 并发现它非常直接地用于从本机库中检索数据,但很难理解如何以相反的方式进行操作,即将结构化数据传递给本机方法。


我将使用我试图调用的库的一部分中的一个小例子。


本机库 typedef 如下:


typedef struct CreateInfo {

    int count;                    // Number of queue infos

    const QueueInfo* queues;      // Zero-or-more queue info structures

} CreateInfo;


typedef struct QueueInfo {

    int count;                    // Number of queue priorities

    const float* priorities;      // 'array' of queue priorities

} QueueInfo;

所以我们有一个CreateInfo指代数字的一个,其中的QueueInfo每一个都包含一个浮点值列表。


这些结构的简单 JNA 实现可能如下(为简洁起见,省略了字段顺序、构造函数等):


public class CreateInfo extends Structure {

    public int count;

    public QueueInfo.ByReference queues;

}


public QueueInfo extends Structure {

    int count;

    public Pointer priorities;

}

所以:

  1. JAN 映射(故意)很幼稚,但它们真的很愚蠢吗?如果是这样,逻辑类型是什么?

  2. 如果我已经有一个数组,QueueInfo我可以简单地将指针设置为该数组的第一个元素吗?还是我必须使用分配一个数组Structure::toArray?这些结构除了默认之外没有构造函数,它们应该有吗?

  3. 我有队列优先级浮点数组,但如何设置指针?它实际上应该是指针还是其他东西?一个浮动[]?

我可以找到很多关于 SO 和一般互联网的问题,用于从本地库接收结构,但对于传递结构化数据的问题相对较少。我发现的例子都对同一个问题使用了不同的方法,这些方法看起来很复杂,但应该很简单(?)所以我对“正确”的方法感到迷茫。

我怀疑我没有问正确的问题,这可能意味着我错过了有关 JNA 的一些基本知识。

希望有好心人能指出上面简单的 JNA 代码有什么问题,以及如何在 Java 端填充数据。


蝴蝶刀刀
浏览 168回答 1
1回答

慕田峪4524236

1 - JNA 映射映射旨在直接将 Java 端类型与相应的本机端类型相关联。当这些映射所需的内存众所周知时,JNA 工作得很好。不幸的是,当要映射的本机内存量是可变的时,这需要一些工作来分配和映射所需的本机内存。有几种方法可以做到这一点,具有不同的抽象/控制级别。2 - 已经有 QueueInfo[](第 1 部分)以您QueueInfo在问题中定义的方式,它没有帮助。您只定义了一个 Java 端类,但Pointer该类暗示了一个本机内存指针。您应该修改您的类以在您的领域扩展Structure和使用。请注意,实例化此结构只会为和分配本机内存。数组本身的内存需要单独分配。 publiccountintPointer3 - 分配浮点数组正如我在评论中提到的,这样做的一种方法是为浮点数组分配本机内存:Memory buffer = new Memory(count * Native.getNativeSize(Float.TYPE));然后假设您已经float[] buf定义,您可以使用将其复制到本机内存中buffer.write(0L, buf, 0, count);然后,您可以将其buffer用作实例 的priorities字段。QueueInfo2 - 已经有 QueueInfo[](第 2 部分)现在问题来了,除非您知道您有一个连续的 C 端数组,否则您不能只将指针设置为第一个元素。您的选择是使用Structure::toArray分配内存(然后填充每个元素)或单独创建(连续)指针数组并Pointer从单独分配的结构中复制值。对于toArray变体,如果直接在生成的数组中设置值,则不需要指针构造函数,但指针构造函数可以使复制(从一个本机内存块到另一个)更容易。概括选项 1:使用浮点数组的方法实例化单独QueueInfo的结构。Pointer.write()创建一个构造函数可能会有所帮助,该构造函数将float[]用作参数并如上所述设置count并分配和设置变量。然后,为结构创建一个 spriorities数组并复制每个元素的引用指针。PointerCreateInfo选项 2:创建Structure::toArray用于分配本机内存的结构数组;然后迭代这个结构并直接QueueInfo在适当的索引处创建结构。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java