Funneling Objects through void*

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Thu Jun 15 16:10:37 UTC 2023


There are few options to do this. In Java 20/21 you can use a 
ScopedValue to set up the implicit parameter that needs to be used for 
the callback, if you want a full Java solution.

Or, as discussed here:

https://mail.openjdk.org/pipermail/panama-dev/2023-May/019079.html

It is also possible to wrap some JNI functions in a small library, and 
then call them using FFM. That will allow you to create, destroy and 
access JNI handles.

As discussed in that email, it is possible that at some point in the 
future, FFM/Linker might provide some more direct support for linking to 
JNI (likely, via some helper class).

Cheers
Maurizio

On 15/06/2023 17:05, Johannes Kuhn wrote:
> When trying to help this StackOverflow question[1], I tried to use 
> `EnumWindows`[2]. EnumWindows takes a callback and a void* parameter 
> and invokes the callback using the toplevel HWND & the passed void* 
> parameter.
>
> Currently I have to create a new upcall stub for every invocation, but 
> if I could funnel some java.lang.Object through the void* parameter, I 
> would only need to create a single upcall, where I retrieve the 
> object, cast it and call some method on it.
>
> Example (pseudo) code:
>
>     public interface EnumWindowsCallback {
>         int callback(long hwnd);
>     }
>     private static int enumWindowsUpcall(long hwnd, MemoryAddress obj) {
>         return (int) ((EnumWindowsCallback) 
> toObject(obj)).callback(hwnd);
>     }
>
>     public static int enumWindows(EnumWindowsCallback cb) throws 
> Throwable {
>         try (Arena arena = Arena.ofConfined()) {
>             return (int) 
> ENUM_WINDOWS_MH.invokeExact(ENUM_WINDOWS_UPCALL, toPointer(arena, cb));
>         }
>     }
>
> One problem is that the arena is not accessible within the callback.
>
>
> Of course it is trivial to write such functionally using a counter and 
> a ConcurrentHashMap, but that is not the only possible implementation.
>
> In fact the JNI functions `newGlobalRef` and `deleteGlobalRef` would 
> provide an adequate implementation.
>
> - Johannes
>
> [1]: 
> https://stackoverflow.com/questions/75620948/how-do-i-get-the-hwnd-of-a-canvas-using-panama/
> [2]: 
> https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enumwindows


More information about the panama-dev mailing list