Home > OS >  Passing pointer to byte array (byte**) to native function and get result array
Passing pointer to byte array (byte**) to native function and get result array

Time:01-14

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**).

The signature of native API follows:

// 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.

How can I retrieve array from this native function?

Actual native function: https://github.com/VOICEVOX/voicevox_core/blob/0.13.0/core/src/core.h#L169

CodePudding user response:

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:

def func(output: PointerByReference): Int

The value being returned is ultimately a 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.

PointerByReference.getValue() returns the Pointer pointed to, removing one level of indirection to get you to 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)
  • Related