Mapping List<String> to char **
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Fri Jun 11 21:29:57 UTC 2021
On 11/06/2021 21:52, John Rose wrote:
> I reproduced this result in the following script, FTR:
>
> http://cr.openjdk.java.net/~jrose/panama/argv-example.jshell
> <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?
What I did was
jshell --add-modules jdk.incubator.foreign
-R--enable-native-access=ALL-UNNAMED
Which seems similar. For now that's the best way, we will plan better
integration with tools such as jshell in the upcoming releases, so that
you can just specify --enable-native-access (and that will be propagated
to the runtime).
>
> 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:
Whoops yes!
>
> 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.
Yeah - I think at some point I was pondering about something like that
for strings - but are right in that it is more general than just strings.
>
> 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.
Seems like a case of a missed check in the implementation. We tried to
check for MemoryAddress.NULL in various places (for instance, NULL is
not a valid target address for a downcall method handle), but the check
in the unsafe string conversion method seems to be missing.
Filed:
https://bugs.openjdk.java.net/browse/JDK-8268633
Thanks
Maurizio
More information about the panama-dev
mailing list