Mapping List<String> to char **

John Rose john.r.rose at oracle.com
Fri Jun 11 20:52:15 UTC 2021


I reproduced this result in the following script, FTR:

http://cr.openjdk.java.net/~jrose/panama/argv-example.jshell

I had to invoke shell with `-R--enable-native-access`
and `-RALL-UNNAMED argv-example.jshell` options,
apparently.  Is there a better way to do that?

Also, Sebastian’s use case often requires an extra null
pointer at the end of the args, so I added that in with
Stream.concat:

var argv = allocator.allocateArray(CLinker.C_POINTER,
Stream.concat(strings.stream().map(s -> CLinker.toCString(s, scope)),
Stream.of(MemoryAddress.NULL)).toArray(Addressable[]::new));

var argc = IntStream.range(0,Integer.MAX_VALUE).filter(
i->MemoryAccess.getAddressAtIndex(argv,i)==MemoryAddress.NULL
).findFirst().getAsInt();

IntStream.range(0,argc).mapToObj(
i->CLinker.toJavaString(MemoryAccess.getAddressAtIndex(argv,i))
).toList();

— John

P.S. It might be worth having a version of allocator.allocateArray
that will *always* add a word or two of all-zero bits to the
end of every block.  That would help with null termination
of all sorts of data structures.  It’s a terrible hack, but I’ve
seen it used in C libraries.

P.P.S.  Changing the argv stream to use rangeClosed crashed
my JVM, naturally:

IntStream.rangeClosed(0,argc).mapToObj(
i->CLinker.toJavaString(MemoryAccess.getAddressAtIndex(argv,i))
).toList();

The problem there was that I fed CLinker.toJavaString
with a null native pointer.  Oops!  It did (for me) raise the
question of whether or how to make the Java/C conversion
routines more null-friendly.


More information about the panama-dev mailing list