Java JNA传递结构,包含指向结构的指针和指向原语的指针
我正在使用JNA,并发现它非常直接地用于从本机库检索数据,但我很难理解如何以另一种方式进行检索,即将结构化数据传递给本机方法 我将使用我试图调用的库的一部分中的一个小示例 本机库typedef如下所示:Java JNA传递结构,包含指向结构的指针和指向原语的指针,java,jna,Java,Jna,我正在使用JNA,并发现它非常直接地用于从本机库检索数据,但我很难理解如何以另一种方式进行检索,即将结构化数据传递给本机方法 我将使用我试图调用的库的一部分中的一个小示例 本机库typedef如下所示: typedef struct CreateInfo { int count; // Number of queue infos const QueueInfo* queues; // Zero-or-more queue info
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实现可以如下所示(为了简洁起见,省略了字段顺序、构造函数等):
因此:
QueueInfo
数组,我可以简单地将指针设置为该数组的第一个元素吗?或者我是否需要使用Structure::toArray
分配数组?这些结构除了默认构造函数之外没有其他构造函数,它们应该有吗希望有一些善良的灵魂能够指出上面幼稚的JNA代码的错误,以及如何在Java端用数据填充它。1-JNA映射 映射被设计为直接将Java端类型与相应的本机端类型相关联。当这些映射所需的内存众所周知时,JNA工作得非常好。不幸的是,当要映射的本机内存量可变时,需要一些工作来分配和映射所需的本机内存。有几种方法可以做到这一点,不同级别的抽象/控制 2-已经有QueueInfo[](第1部分) 按照您在问题中定义
QueueInfo
的方式,这没有什么帮助。您只定义了一个Java端类,但是指针
类暗示了一个本机内存指针。您应该修改类以扩展结构
,并在计数
字段上使用公共
。请注意,实例化此结构将仅为int
和指针
分配本机内存。阵列本身的内存需要单独分配
3-分配浮点数组
正如我在评论中提到的,要为浮点数组分配本机内存:
Memory buffer = new Memory(count * Native.getNativeSize(Float.TYPE));
然后假设您定义了float[]buf
,您可以使用
buffer.write(0L, buf, 0, count);
然后,您可以使用buffer
作为QueueInfo
实例的priorities
字段
2-已经有QueueInfo[](第2部分)
现在来看这个问题,除非您知道有一个连续的C端数组,否则不能只设置指向第一个元素的指针。您可以选择使用Structure::toArray
分配内存(然后填充每个元素),或者单独创建一个(连续的)指针数组,并从单独分配的结构复制指针
值。对于toArray
变量,如果直接在生成的数组中设置值,则不需要指针构造函数,但指针构造函数可以使复制(从一个本机内存块复制到另一个本机内存块)更容易
摘要
选项1:使用浮点数组的指针.write()
方法实例化单独的QueueInfo
结构。创建一个构造函数可能会很有帮助,该构造函数将float[]
作为参数,设置count
并如上所述分配和设置优先级
变量。然后,为CreateInfo
结构创建一个Pointer
s数组,并复制到每个元素的引用指针上
选项2:使用
Structure::toArray
创建结构数组以分配本机内存;然后迭代此结构,并在适当的索引处直接创建QueueInfo
结构。因此,问题2的“标准”答案似乎是必须使用structure::toArray
实例化一个结构数组,例如final QueueInfo[/queues=(QueueInfo[])new QueueInfo().toArray(size);对于(int n=0;n
对#1的部分回答是“指向数组结构的指针”字段应该是结构。通过引用
。相应地修改了JNA。#1:取决于你对愚蠢的定义#2:使用Structure.toArray()
方法更方便,因为您不必从本机内存read()
每个结构。您还可以使用指针
,并使用指针构造函数从适当的偏移量实例化结构#3:指针
通常是一个很好的映射。最终得到的是一个本机分配的缓冲区,您可以使用指针.getFloatArray()
来检索值。@DanielWiddis不确定“检索值”是什么意思?我不需要检索任何东西,我已经在Java代码中有了数据,我只需要将它作为结构中的字段传递给本机库。还是我没有领会你的意思?也许您可以提供一个wha的快速伪代码片段
buffer.write(0L, buf, 0, count);