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