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

问题描述 投票:1回答:1

我正在使用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,每个public class CreateInfo extends Structure { public int count; public QueueInfo.ByReference queues; } public QueueInfo extends Structure { int count; public Pointer priorities; } 都包含一个浮点值列表。

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

QueueInfo

所以:

  1. JAN映射(故意)天真,但它们真的很愚蠢吗?如果是这样的逻辑类型是什么?
  2. 如果我已经有一个Structure::toArray数组,我可以简单地将指针设置为该数组的第一个元素吗?或者我是否必须使用QueueInfo分配数组?如果它们有结构,那么结构没有默认的构造函数?
  3. 我有队列优先级浮点数组但是如何设置指针?它应该是指针还是其他东西?一个浮点[]?

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

我怀疑我不是在问正确的问题,这可能意味着我错过了一些关于JNA的基本信息。

希望某种灵魂可以指出上面的天真JNA代码有什么问题,以及如何在Java端填充数据。

java jna
1个回答
1
投票

1 - Jana Mappings

映射旨在将Java端类型直接与相应的本机端类型相关联。当这些映射所需的内存众所周知时,JNA可以很好地工作。不幸的是,当要映射的本机内存量是可变的时,这需要一些工作来分配和映射所需的本机内存。有几种方法可以实现这一点,具有不同的抽象/控制水平。

2 - 已经有QueueInfo [](第1部分)

通过你在问题中定义Pointer的方式,它没有用。您只定义了一个Java端类,但Structure类意味着一个本机内存指针。您应修改您的类以扩展public并在count字段上使用int。请注意,实例化此结构只会为Pointerone way of doing this分配本机内存。阵列本身的内存需要单独分配。

3 - 分配float数组

正如我在评论中提到的,Memory buffer = new Memory(count * Native.getNativeSize(Float.TYPE)); 是为float数组分配本机内存:

float[] buf

然后假设您已定义buffer.write(0L, buf, 0, count); ,您可以使用将其复制到本机内存中

buffer

然后你可以使用priorities作为QueueInfo实例的Structure::toArray字段。

2 - 已经有QueueInfo [](第2部分)

现在问题是,除非您知道有一个连续的C端数组,否则不能只将指针设置为第一个元素。您的选择是使用Pointer分配内存(然后填充每个元素)或单独创建(连续)指针数组并从单独分配的结构复制toArray值。对于QueueInfo变体,如果直接在生成的数组中设置值,则不需要指针构造函数,但指针构造函数可以更容易地进行复制(从一个本机内存块到另一个)。

摘要

选项1:使用Pointer.write()方法为浮点数组实例化单独的float[]结构。创建一个构造函数可能会有所帮助,该构造函数将count作为参数并设置priorities并分配和设置Pointer变量,如上所述。然后,为CreateInfo结构创建一个Structure::toArrays数组,并复制每个元素的引用指针。

选项2:使用QueueInfo创建一个结构数组来分配本机内存;然后迭代这个结构并直接在适当的索引处创建qazxswpoi结构。

© www.soinside.com 2019 - 2024. All rights reserved.