简体   繁体   English

JNA返回结构数组作为参数

[英]JNA return array of struct as parameter

I have a C function, which creates an array of structs我有一个 C function,它创建了一个结构数组

int createArray(myStruct** data_array);

From C I call the function like this:从 C 我这样称呼 function :

myStruct* data_array;
int size = createArray(&data_array);

I want to call createArray in a similar way with JNA.我想以与 JNA 类似的方式调用createArray I've generated the wrapper using JNAerator.我已经使用 JNAerator 生成了包装器。

int createArray(myStruct.ByReference[] data_array);

I don't know what to pass to the JNA method createArray since data_array is actually a output parameter.我不知道将什么传递给 JNA 方法createArray ,因为data_array实际上是一个 output 参数。 I actually think the generated JNA method is wrong since I don't want to pass an array of myStruct , I want to receive one.我实际上认为生成的 JNA 方法是错误的,因为我不想传递myStruct的数组,我想接收一个。

Shouldn't the parameter of the JNA method be PointerByReference ? JNA 方法的参数不应该是PointerByReference吗?

Here are some tries that didn't worked for me以下是一些对我不起作用的尝试

PointerByReference ptr = new PointerByReference();
int size = api.createArray(ptr); //Invalid memory access
myStruct.ByReference[] array = new myStruct.ByReference[10];
Arrays.fill(stLinks, new myStruct.ByReference()); //without this I get NullpointerException
int size = api.createArray(array); //Invalid memory access

Shouldn't the parameter of the JNA method be PointerByReference ? JNA 方法的参数不应该是PointerByReference吗?

Well it could be.那么它可能是。 Should it?应该是? Depends on whether you want type safety or not.取决于您是否需要类型安全。

The important point here is that native arrays are contiguous blocks of memory, so an array of fixed size structures is just a pointer with offsets for each element of the array.这里重要的一点是,原生 arrays 是 memory 的连续块,因此固定大小结构的数组只是一个指针,其中包含数组中每个元素的偏移量。

If you pass an array as an argument, it will receive the pointer to the first element ( myStruct[0] ) and auto-write the native memory to fill it.如果您将数组作为参数传递,它将接收指向第一个元素 ( myStruct[0] ) 的指针并自动写入本机 memory 来填充它。

Alternately you could pass a PointerByReference and instantiate an array from it.或者,您可以传递一个PointerByReference并从中实例化一个数组。 A little lower-level interface and you have more direct control over when memory is read and written.一个低级接口,您可以更直接地控制 memory 何时被读取和写入。

The most important thing here is just to realize who is allocating the memory for the array, and making sure it's released.这里最重要的是要知道是谁在为阵列分配 memory,并确保它已被释放。 The rest is mostly up to coding style and readability and type safety. rest 主要取决于编码风格、可读性和类型安全性。

Seems like the problem with Invalid memory access was caused by other side effects.似乎无效 memory 访问的问题是由其他副作用引起的。 I had to call other functions from the API before I can use createArray.我必须先从 API 调用其他函数,然后才能使用 createArray。

The working code is now:现在的工作代码是:

PointerByReference ptr = new PointerByReference();
            
int size = api.createArray(ptr);
            
Pointer ptrToFirst = ptr.getValue();
myStruct firstElement = new myStruct(ptrToFirst);
myStruct[] array = (myStruct []) firstElement.toArray(size);

//Work with Array

api.deleteArray();          

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM