Array from java to C (SNI)


#1

Hi,

Is it possible to send an array from java function and receive it in C function, using SNI ?

For example:

  • native int sendArray(int[] array) => java
  • jint com_package_utils_sendArray(jint* array) => C

If it is possible, what would be the implementation of the C function to get the size and the data of the array in C ?

Thanks


#2

Hi @Thomas

Yes it is possible, please refer to the SNI specification [1] in the section 3.2.2, we can read the following:

Note that SNI supports only one dimension arrays and the array should be immortal [2].

Also be careful of your naming convention and modifiers, the example you used is incorrect, it should be something like this:

  • Java:
    static native int sendArray(int[] array)

  • C:
    jint Java_com_package_utils_Classname_sendArray(jint* array)
    Assuming sendArray is the only function of this name, otherwise you forced to specify the whole signature.

Hope it’ll help.

Gaëtan

[1] http://e-s-r.net/download/specification/ESR-SPE-0012-SNI_GT-1.2-H.pdf
[2] http://e-s-r.net/download/specification/ESR-SPE-0001-BON-1.2-F.pdf section 3.2


#3

Hi,

Thanks @gaetan.harel , it works.

We should use immortal array if there is no copy of the array. But a “classic” array should do the trick if I copy the array in my C function right ? No side effects in this case ?


#4

Hi,

I was saying that the arrays that are crossing the frontier between Java and C should be immortals.
After that you can use the immortal array in C as you wish.
I did not quite understood what you meant by:

But a “classic” array should do the trick if I copy the array in my C function right ?

Regards,
Gaëtan


#5

Hi,

I mean I can use memcpy in my SNI, and I do not need immortal array, right ?


#6

Hi,

You can safely copy to and from the immortal array in C, but the array that is passed through the native Java method must be immortal.

Regards,
Gaëtan


#7

Hi,

Why immortal array is mandatory ? The array given from java can’t be delete by the garbage collector as long as the SNI does not return. So memcpy is safe I think, I don’t see any issue, could you explain me why immortal array is mandatory ?

But if immortal array is indeed mandatory, how can I delete it from my java app ? I don’t want it to survive the whole life of my application, I just need it for the call to the SNI. The API does not seem to support the deletion of an immortal array. Any idea ?

Thanks


#8

Hi,

Yeah you are right, the immortal array is indeed … immortal :slight_smile: and never garbage collected. There is no API to free it.

The problem here lies in the implementation of the SNI calls for safety and performance purpose.
You say The array given from java can’t be delete by the garbage collector as long as the SNI does not return.:

  • once on the native is called, if you are blocking the virtual machine in your native thread, you are right the garbage collector is never triggered
  • however if your are using your array in another native thread, the garbage collector could be triggered and free your array (since it “belongs” to the Java heap space)

What is usually done with our libraries are that we create immortal native buffers for all native calls on this library, so that is reusable. If you want you can use a pool of immortal arrays by using the API in PoolOfImmortalByteBuffers [1]

As of SNI 1.3 (not available publicly), we have the option to pass a non-immortal array at the condition that this array is never used in another thread.

Gaëtan

[1] http://developer.microej.com/javadoc/microej_4.1/foundation/ej/sni/PoolOfImmortalByteBuffers.html