Funneling Objects through void*
Johannes Kuhn
info at j-kuhn.de
Thu Jun 15 16:34:35 UTC 2023
Yes, that would work fine.
Requires a small native library (or hacking into
jdk.internal.loader.NativeLibrary so it "finds" my upcall when I try to
invoke a native method).
One possible implementation of that primitive.
- Johannes
On 15-Jun-23 18:27, Maurizio Cimadamore wrote:
>
> On 15/06/2023 17:18, Johannes Kuhn wrote:
>> Yes, I have read the thread. That StackOverflow question (and the
>> thread) was just an other trigger to discuss a IMHO a more fundamental
>> primitive: Passing an java object through a void* pointer.
>
>
> If you can create a JNI reference from an object and get a segment for
> it, you can also pass it to a foreign function, no?
>
> It seems to me that you want to be able to pass the object _directly_ to
> the function, which, to me, seems like a lot of accidental complexity
> for the linker machinery, with not a lot of upside (if you have some
> _other_ way to go Object -> segment).
>
>>
>>
>> I just want a pair of methods that turn an object into a pointer and
>> back - preferably with a deterministic "deallocation".
>> How that is implemented is a different story.
>
> In the thread I quoted, there's this:
>
>> native long makeGlobalRef(Object o) // call NewGlobalRef, cast result to
>> jlong and return
>> native void destroyGlobalRef(long ref) // cast to jobject, then call
>> DeleteGlobalRef
> Wouldn't that pair of functions allow you to do what you want? It is
> fairly simple to provide FFM bindings for these. For instance, few weeks
> ago I created this class (note, JNIUtils define the native methods to
> bind to the functionality described above):
>
> ```java
> import java.lang.foreign.Arena;
> import java.lang.foreign.MemorySegment;
>
> public class JNIUtilsWrapper {
> public static MemorySegment newGlobalRef(Object o, Arena arena) {
> return MemorySegment.ofAddress(JNIUtils.makeGlobalRef(o))
> .reinterpret(arena, (ref) ->
> JNIUtils.destroyGlobalRef(ref.address()));
> }
>
> public static Object getRef(MemorySegment ref) {
> return JNIUtils.readGlobalRef(ref.address());
> }
> }
> ```
>
> Which I then used like so:
>
> ```java
> try (Arena arena = Arena.ofConfined()) {
> MemorySegment str = JNIUtilsWrapper.newGlobalRef("hello", arena);
> System.out.println(JNIUtilsWrapper.getRef(str));
> }
> ```
>
> Maurizio
>
More information about the panama-dev
mailing list