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