1

I create this entrypoint on the Java side:

    @CEntryPoint(name = "printStruct")
    public static void printStruct(IsolateThread thread, VoidPointer message, int size) {
        System.out.println(message.isNull());
        ByteBuffer buf = CTypeConversion.asByteBuffer(message, size);

        System.out.println(new String(buf.array()));
    }

It's compiled by the GraalVM native-image compiler and libexample.h is generated with:

    void printStruct(graal_isolatethread_t* thread, void* message, int size);

Then I build and run C code:

   int main() {
     graal_isolatethread_t *thread;


     int i = graal_create_isolate(NULL, NULL, &thread);
     if (i != 0) {
       printf("Error creating isolate %d", i);
       return -1;
     }
     printStruct(thread, "heh", 3);
     i = graal_tear_down_isolate(thread);
     if (i != 0) {
       printf("Error tearing down isolate %d", i);
     }

     return 0;
   }

It builds fine but being executed outputs:

  false
  java.lang.UnsupportedOperationException: null
     at java.nio.ByteBuffer.array(ByteBuffer.java:1471)
     at examples.App.printStruct(App.java:26)

I couldn't find any explanation of that. The documentation of asByteArray says:

Creates a ByteBuffer that refers to the native memory at the specified address.

So the message is not a null pointer but I cannot access byte array I passed.

egor10_4
  • 331
  • 2
  • 9

1 Answers1

2

you need to transfer the bytes from the buffer to destination array:

    var buf = CTypeConversion.asByteBuffer(message, size);
    byte[] arr = new byte[buf.remaining()];
    buf.get(arr);
  • So it copies the data to ByteBuffer first and then copies additionally to the byte array, I wonder if there is a way to copy it only once? – egor10_4 Oct 28 '22 at 16:26
  • 1
    its not necessarily copied (if meaning is backed by an array) - this thread might be helpful https://stackoverflow.com/questions/31062973/java-byte-array-to-bytebuffer-or-bytebuffer-to-byte-array-convertion-without-co – Maxim Zinger Nov 15 '22 at 13:39