[英]Passing pointer to byte array (byte**) to native function and get result array
I'm trying to use JNA to call native API in Scala. I don't know how to pass pointer of array of byte ( byte**
).我正在尝试使用 JNA 在 Scala 中调用本机 API。我不知道如何传递字节数组指针 ( byte**
)。
The signature of native API follows:原生API的签名如下:
// this function mallocs some array buffer and stores it to passed pointer value
int func(byte **output);
Then I tried to pass pointer like this:然后我试着像这样传递指针:
class NativeLibrary extends Library {
def func(output: Array[Byte]) // doesn't work. thats' for byte*, not byte**
def func(output: Array[Array[Byte]]) // doesn't work. JNA doesn't support this type
def func(output: Memory) // works, but I don't know how to get inner array
}
Both don't seem to work, returning broken pointer value or raising SEGV.两者似乎都不起作用,返回损坏的指针值或提高 SEGV。
How can I retrieve array from this native function?如何从此本机 function 检索数组?
Actual native function: https://github.com/VOICEVOX/voicevox_core/blob/0.13.0/core/src/core.h#L169实际原生function: https://github.com/VOICEVOX/voicevox_core/blob/0.13.0/core/src/core.h#L169
The **
represents a pointer to a pointer to a byte (the beginning of the byte array of interest), so the correct implementation is a PointerByReference
: **
表示指向字节指针的指针(感兴趣的字节数组的开头),因此正确的实现是PointerByReference
:
def func(output: PointerByReference): Int
The value being returned is ultimately a Pointer
.返回的值最终是一个Pointer
。 Since 'Memory' is a subclass of Pointer
designed for Java-level allocation of memory. Since it's a subclass it appears to work, but is not the correct implementation.由于“Memory”是为 memory 的 Java 级分配而设计的Pointer
的子类。由于它是一个子类,因此它似乎可以工作,但不是正确的实现。
PointerByReference.getValue()
returns the Pointer
pointed to, removing one level of indirection to get you to byte*
: PointerByReference.getValue()
返回指向的Pointer
,移除一级间接访问byte*
:
// val size = size of buffer that you are passing to the actual function
val pbr = new PointerByReference()
// allocates the array and returns pointer to it
val resultCode = NativeLibrary.INSTANCE.func(pbr)
// get the pointer to the actual data
val dataPointer = pbr.getValue()
// get the data as a byte array
val data = dataPointer.getByteArray(0, size)
// later to free the `byte*`
resultCode = voicevox_wav_free(dataPointer)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.