Hi Rob, Delegating caller sensitive methods can be tricky.
Besides the obvious solutions with StackWalker and/or Lookup objects I've sometimes used an abstract class that must be extended by users of my library. This may be more trouble in your case than the other solutions though. In your situation it would be something like this. // Defined in your library and extendable by users of your library public abstract class NativeLoader { protected abstract MethodHandle downcallHandle(Linker linker, MemorySegment address, FunctionDescriptor function, Linker.Option... options); public final <T> T load(Class<T> interFace) { .. do stuff. call this.downcallHandle .. do more stuff } } // Usage by other library class UsageByOtherLibrary { private static final NativeLoader NL = new NativeLoader() { protected MethodHandle downcallHandle(Linker linker, MemorySegment address, FunctionDescriptor function, Option... options) { return linker.downcallHandle(address, function, options); } }; public void main() { SomeInterface si = NL.load(SomeInterface.class); } } The actual call to Linker.downcallHandle is now only performed by the user of your library. So depending on what you do, you might even be able to avoid requiring enabling native access for your library. Only the libraries that use your library would need it. /Kasper On Thu, 16 Nov 2023 at 19:21, Rob Spoor <open...@icemanx.nl> wrote: > > On 16/11/2023 18:15, Maurizio Cimadamore wrote: > > > > On 16/11/2023 16:54, Rob Spoor wrote: > >> Hi Maurizio, > >> > >> I don't think you understand what my module is doing. For instance, > >> it's not specifying the downcall method handles themselves, it's just > >> making it easy to define them. Maybe a small example would show what > >> I'm doing. > >> > >> Consider the following partial interface from JNA: > >> > >> public interface Kernel32 extends StdCallLibrary, WinNT, Wincon { > >> > >> /** The instance. */ > >> Kernel32 INSTANCE = Native.load("kernel32", Kernel32.class, > >> W32APIOptions.DEFAULT_OPTIONS); > >> > >> int GetLastError(); > >> } > >> > >> What JNA is doing is creating an implementation based on this > >> interface that delegates to the native kernel32 library. This is all > >> done through the Native.load method.