Mapping List<String> to char **
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Fri Jun 11 14:50:10 UTC 2021
Hi,
The API we have in 17 has the ability to create a so called
SegmentAllocator:
https://download.java.net/java/early_access/jdk17/docs/api/jdk.incubator.foreign/jdk/incubator/foreign/SegmentAllocator.html
A SegmentAllocator has a method to allocate a contiguous array of addresses:
https://download.java.net/java/early_access/jdk17/docs/api/jdk.incubator.foreign/jdk/incubator/foreign/SegmentAllocator.html#allocateArray(jdk.incubator.foreign.ValueLayout,jdk.incubator.foreign.Addressable%5B%5D)
I believe that by combining these bits you should be able to do what you
want - e.g.
```
jshell> import jdk.incubator.foreign.*;
jshell> List<String> strings = List.of("a", "b", "c");
strings ==> [a, b, c]
jshell> var scope = ResourceScope.newConfinedScope();
scope ==> jdk.internal.foreign.ConfinedScope at 37f8bb67
jshell> var allocator = SegmentAllocator.ofScope(scope);
allocator ==> jdk.internal.foreign.ConfinedScope at 37f8bb67
jshell> var cstrings = allocator.allocateArray(CLinker.C_POINTER,
strings.stream().map(s -> CLinker.toCString(s,
scope)).toArray(Addressable[]::new));
cstrings ==> MemorySegment{ id=0x72ee5071 limit: 24 }
jshell> CLinker.toJavaString(MemoryAccess.getAddressAtIndex(cstrings, 0));
$6 ==> "a"
jshell> CLinker.toJavaString(MemoryAccess.getAddressAtIndex(cstrings, 1));
$7 ==> "b"
jshell> CLinker.toJavaString(MemoryAccess.getAddressAtIndex(cstrings, 2));
$8 ==> "c"
```
I hope this helps.
Maurizio
On 11/06/2021 15:32, Sebastian Stenzel wrote:
> Hi,
>
> imagine you want to invoke a native method with (among others) these params:
>
> int argc, char **argv
>
> On the Java side I have a `List<String>`.
>
> Currently, ...
>
> 1. I create a new SequenceLayout of type MemoryLayouts.ADDRESS and of size `argc`
> 2. I allocate a new MemorySegment `argv` using aforementioned layout
> 3. For each of my elements, I call CLinker.toCString and fill in the address of the returned segment into `argv`
>
> I feel like there should be an easier way to achieve this. Is there some utility to create a MemorySegment from an array of addresses? (I know I can create an array of longs, but I don't want to rely on a 64 bit architecture).
>
> Thanks,
> Sebastian
More information about the panama-dev
mailing list