<div dir="ltr"><div>I've been using jextract successfully for some time now and it has made it very easy to call into various Windows. Great work.</div><div><br></div><div>One area which seems a bit verbose
is the handling of the functional interface callbacks for upcalls. For example, the qsort compare callback is as follows (I've shortened the jextract version here):</div><div><br></div><div><div style="background-color:rgb(255,255,255);padding:0px 0px 0px 2px"><div style="color:rgb(0,0,0);background-color:rgb(255,255,255);font-family:"Consolas";font-size:10pt;white-space:pre"><p style="margin:0px"><span style="color:rgb(127,0,85);font-weight:bold">public</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">class</span><span style="color:rgb(0,0,0)"> QsortCompareFunc {</span></p><p style="margin:0px"><br></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> QsortCompareFunc() { }</span></p><p style="margin:0px"><br></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(63,95,191)">/** The function pointer signature, expressed as a functional interface */</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">public</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">interface</span><span style="color:rgb(0,0,0)"> Function {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">int</span><span style="color:rgb(0,0,0)"> apply(MemorySegment </span><span style="color:rgb(106,62,62)">_x0</span><span style="color:rgb(0,0,0)">, MemorySegment </span><span style="color:rgb(106,62,62)">_x1</span><span style="color:rgb(0,0,0)">);</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> }</span></p><p style="margin:0px"><br></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">private</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">static</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">final</span><span style="color:rgb(0,0,0)"> FunctionDescriptor </span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">$DESC</span><span style="color:rgb(0,0,0)"> = FunctionDescriptor.</span><span style="color:rgb(0,0,0);font-style:italic">of</span><span style="color:rgb(0,0,0)">(</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> C_h.C_INT,</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> C_h.C_POINTER,</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> C_h.C_POINTER</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> );</span></p><p style="margin:0px"><br></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(63,95,191)">/** The descriptor of this function pointer */</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">public</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">static</span><span style="color:rgb(0,0,0)"> FunctionDescriptor descriptor() {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">return</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">$DESC</span><span style="color:rgb(0,0,0)">;</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> }</span></p><p style="margin:0px"><br></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">private</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">static</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">final</span><span style="color:rgb(0,0,0)"> MethodHandle </span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">UP$MH</span><span style="color:rgb(0,0,0)"> = C_h.upcallHandle(QsortCompareFunc.Function.</span><span style="color:rgb(127,0,85);font-weight:bold">class</span><span style="color:rgb(0,0,0)">, </span><span style="color:rgb(42,0,255)">"apply"</span><span style="color:rgb(0,0,0)">, </span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">$DESC</span><span style="color:rgb(0,0,0)">);</span></p><p style="margin:0px"><br></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(63,95,191)">/**</span></p><p style="margin:0px"><span style="color:rgb(63,95,191)"> * Allocates a new upcall stub, whose implementation is defined by {@code fi}.</span></p><p style="margin:0px"><span style="color:rgb(63,95,191)"> * The lifetime of the returned segment is managed by {@code arena}</span></p><p style="margin:0px"><span style="color:rgb(63,95,191)"> */</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">public</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">static</span><span style="color:rgb(0,0,0)"> MemorySegment allocate(QsortCompareFunc.Function </span><span style="color:rgb(106,62,62)">fi</span><span style="color:rgb(0,0,0)">, Arena </span><span style="color:rgb(106,62,62)">arena</span><span style="color:rgb(0,0,0)">) {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">return</span><span style="color:rgb(0,0,0)"> Linker.</span><span style="color:rgb(0,0,0);font-style:italic">nativeLinker</span><span style="color:rgb(0,0,0)">().upcallStub(</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">UP$MH</span><span style="color:rgb(0,0,0)">.bindTo(</span><span style="color:rgb(106,62,62)">fi</span><span style="color:rgb(0,0,0)">), </span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">$DESC</span><span style="color:rgb(0,0,0)">, </span><span style="color:rgb(106,62,62)">arena</span><span style="color:rgb(0,0,0)">);</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> }</span></p><p style="margin:0px"><br></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">private</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">static</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">final</span><span style="color:rgb(0,0,0)"> MethodHandle </span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">DOWN$MH</span><span style="color:rgb(0,0,0)"> = Linker.</span><span style="color:rgb(0,0,0);font-style:italic">nativeLinker</span><span style="color:rgb(0,0,0)">().downcallHandle(</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">$DESC</span><span style="color:rgb(0,0,0)">);</span></p><p style="margin:0px"><br></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(63,95,191)">/**</span></p><p style="margin:0px"><span style="color:rgb(63,95,191)"> * Invoke the upcall stub {@code funcPtr}, with given parameters</span></p><p style="margin:0px"><span style="color:rgb(63,95,191)"> */</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">public</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">static</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">int</span><span style="color:rgb(0,0,0)"> invoke(MemorySegment </span><span style="color:rgb(106,62,62)">funcPtr</span><span style="color:rgb(0,0,0)">,MemorySegment </span><span style="color:rgb(106,62,62)">_x0</span><span style="color:rgb(0,0,0)">, MemorySegment </span><span style="color:rgb(106,62,62)">_x1</span><span style="color:rgb(0,0,0)">) {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">try</span><span style="color:rgb(0,0,0)"> {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">return</span><span style="color:rgb(0,0,0)"> (</span><span style="color:rgb(127,0,85);font-weight:bold">int</span><span style="color:rgb(0,0,0)">) </span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">DOWN$MH</span><span style="color:rgb(0,0,0)">.invokeExact(</span><span style="color:rgb(106,62,62)">funcPtr</span><span style="color:rgb(0,0,0)">, </span><span style="color:rgb(106,62,62)">_x0</span><span style="color:rgb(0,0,0)">, </span><span style="color:rgb(106,62,62)">_x1</span><span style="color:rgb(0,0,0)">);</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> } </span><span style="color:rgb(127,0,85);font-weight:bold">catch</span><span style="color:rgb(0,0,0)"> (Throwable </span><span style="color:rgb(106,62,62)">ex$</span><span style="color:rgb(0,0,0)">) {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">throw</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">new</span><span style="color:rgb(0,0,0)"> AssertionError(</span><span style="color:rgb(42,0,255)">"should not reach here"</span><span style="color:rgb(0,0,0)">, </span><span style="color:rgb(106,62,62)">ex$</span><span style="color:rgb(0,0,0)">);</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> }</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> }</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">}</span></p></div></div></div><div><br></div><div>I made a few changes in jextract to make the callbacks generate interface rather than a class, adding a helper record Upcall to do most of the actions:</div><div><br></div><div><div style="background-color:rgb(255,255,255);padding:0px 0px 0px 2px"><div style="color:rgb(0,0,0);background-color:rgb(255,255,255);font-family:"Consolas";font-size:10pt;white-space:pre"><p style="margin:0px"><span style="color:rgb(127,0,85);font-weight:bold">public</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">interface</span><span style="color:rgb(0,0,0)"> QsortCompareFunc {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(63,95,191)">/** The function pointer signature, expressed as a functional interface */</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">int</span><span style="color:rgb(0,0,0)"> apply(MemorySegment </span><span style="color:rgb(106,62,62)">_x0</span><span style="color:rgb(0,0,0)">, MemorySegment </span><span style="color:rgb(106,62,62)">_x1</span><span style="color:rgb(0,0,0)">);</span></p><p style="margin:0px"><br></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">static</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">final</span><span style="color:rgb(0,0,0)"> C_h.Upcall<QsortCompareFunc> </span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">UPCALL</span><span style="color:rgb(0,0,0)"> = </span><span style="color:rgb(127,0,85);font-weight:bold">new</span><span style="color:rgb(0,0,0)"> C_h.Upcall<>(QsortCompareFunc.</span><span style="color:rgb(127,0,85);font-weight:bold">class</span><span style="color:rgb(0,0,0)">, </span><span style="color:rgb(42,0,255)">"apply"</span><span style="color:rgb(0,0,0)">, FunctionDescriptor.</span><span style="color:rgb(0,0,0);font-style:italic">of</span><span style="color:rgb(0,0,0)">(</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> C_h.</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">C_INT</span><span style="color:rgb(0,0,0)">,</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> C_h.</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">C_POINTER</span><span style="color:rgb(0,0,0)">,</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> C_h.</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">C_POINTER</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> ));</span></p><p style="margin:0px"><br></p><div style="background-color:rgb(255,255,255);padding:0px 0px 0px 2px"><div style="color:rgb(0,0,0);background-color:rgb(255,255,255);font-family:"Consolas";font-size:10pt;white-space:pre"><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(63,127,95)">// </span><span style="color:rgb(63,127,95)">A </span><span style="color:rgb(63,127,95)">new upcall stub </span><span style="color:rgb(63,127,95)">is </span><span style="background-color:rgb(255,255,255);padding:0px 0px 0px 2px"><span style="color:rgb(0,0,0);background-color:rgb(255,255,255);font-family:"Consolas";font-size:10pt;white-space:pre"><span style="color:rgb(63,127,95)">allocated </span></span></span><span style="color:rgb(63,127,95)">by</span>:</p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(63,127,95)">// MemorySegment funcPtr = QsortCompareFunc.UPCALL.allocate(fi,arena)</span></p><p style="margin:0px"><br></p></div></div><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(63,95,191)">/**</span></p><p style="margin:0px"><span style="color:rgb(63,95,191)"> * Invoke the upcall stub {@code funcPtr}, with given parameters</span></p><p style="margin:0px"><span style="color:rgb(63,95,191)"> */</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">public</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">static</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">int</span><span style="color:rgb(0,0,0)"> invoke(MemorySegment </span><span style="color:rgb(106,62,62)">funcPtr</span><span style="color:rgb(0,0,0)">,MemorySegment </span><span style="color:rgb(106,62,62)">_x0</span><span style="color:rgb(0,0,0)">, MemorySegment </span><span style="color:rgb(106,62,62)">_x1</span><span style="color:rgb(0,0,0)">) {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">try</span><span style="color:rgb(0,0,0)"> {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">return</span><span style="color:rgb(0,0,0)"> (</span><span style="color:rgb(127,0,85);font-weight:bold">int</span><span style="color:rgb(0,0,0)">) </span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">UPCALL</span><span style="color:rgb(0,0,0)">.downcall().invokeExact(</span><span style="color:rgb(106,62,62)">funcPtr</span><span style="color:rgb(0,0,0)">, </span><span style="color:rgb(106,62,62)">_x0</span><span style="color:rgb(0,0,0)">, </span><span style="color:rgb(106,62,62)">_x1</span><span style="color:rgb(0,0,0)">);</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> } </span><span style="color:rgb(127,0,85);font-weight:bold">catch</span><span style="color:rgb(0,0,0)"> (Throwable </span><span style="color:rgb(106,62,62)">ex$</span><span style="color:rgb(0,0,0)">) {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">throw</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">new</span><span style="color:rgb(0,0,0)"> AssertionError(</span><span style="color:rgb(42,0,255)">"should not reach here"</span><span style="color:rgb(0,0,0)">, </span><span style="color:rgb(106,62,62)">ex$</span><span style="color:rgb(0,0,0)">);</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> }</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> }</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">}</span></p></div></div><br></div><div>This reduces the definition somewhat, as long as the top level header has a record to handle all callback interfaces:</div><div><br></div><div><div style="background-color:rgb(255,255,255);padding:0px 0px 0px 2px"><div style="color:rgb(0,0,0);background-color:rgb(255,255,255);font-family:"Consolas";font-size:10pt;white-space:pre"><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">public</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">record</span><span style="color:rgb(0,0,0)"> Upcall<FunctionInterface>(FunctionDescriptor </span><span style="color:rgb(106,62,62)">descriptor</span><span style="color:rgb(0,0,0)">, MethodHandle </span><span style="color:rgb(106,62,62)">upcall</span><span style="color:rgb(0,0,0)">, MethodHandle </span><span style="color:rgb(106,62,62)">downcall</span><span style="color:rgb(0,0,0)">) {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">public</span><span style="color:rgb(0,0,0)"> Upcall(Class<FunctionInterface> </span><span style="color:rgb(106,62,62)">fi</span><span style="color:rgb(0,0,0)">, String </span><span style="color:rgb(106,62,62)">name</span><span style="color:rgb(0,0,0)">, FunctionDescriptor </span><span style="color:rgb(106,62,62)">descriptor</span><span style="color:rgb(0,0,0)">) {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">this</span><span style="color:rgb(0,0,0)">(</span><span style="color:rgb(106,62,62)">descriptor</span><span style="color:rgb(0,0,0)">, </span><span style="color:rgb(0,0,0);font-style:italic">upcallHandle</span><span style="color:rgb(0,0,0)">(</span><span style="color:rgb(106,62,62)">fi</span><span style="color:rgb(0,0,0)">, </span><span style="color:rgb(106,62,62)">name</span><span style="color:rgb(0,0,0)">, </span><span style="color:rgb(106,62,62)">descriptor</span><span style="color:rgb(0,0,0)">), Linker.</span><span style="color:rgb(0,0,0);font-style:italic">nativeLinker</span><span style="color:rgb(0,0,0)">().downcallHandle(</span><span style="color:rgb(106,62,62)">descriptor</span><span style="color:rgb(0,0,0)">));</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> }</span></p><p style="margin:0px"><br></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(63,95,191)">/** Find Java method handle of interface for upcall from native </span><span style="color:rgb(127,127,159)">-></span><span style="color:rgb(63,95,191)"> Java */</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">public</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">static</span><span style="color:rgb(0,0,0)"> MethodHandle upcallHandle(Class<?> </span><span style="color:rgb(106,62,62)">fi</span><span style="color:rgb(0,0,0)">, String </span><span style="color:rgb(106,62,62)">name</span><span style="color:rgb(0,0,0)">, FunctionDescriptor </span><span style="color:rgb(106,62,62)">fdesc</span><span style="color:rgb(0,0,0)">) {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">try</span><span style="color:rgb(0,0,0)"> {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">return</span><span style="color:rgb(0,0,0)"> MethodHandles.</span><span style="color:rgb(0,0,0);font-style:italic">lookup</span><span style="color:rgb(0,0,0)">().findVirtual(</span><span style="color:rgb(106,62,62)">fi</span><span style="color:rgb(0,0,0)">, </span><span style="color:rgb(106,62,62)">name</span><span style="color:rgb(0,0,0)">, </span><span style="color:rgb(106,62,62)">fdesc</span><span style="color:rgb(0,0,0)">.toMethodType());</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> } </span><span style="color:rgb(127,0,85);font-weight:bold">catch</span><span style="color:rgb(0,0,0)"> (ReflectiveOperationException </span><span style="color:rgb(106,62,62)">ex</span><span style="color:rgb(0,0,0)">) {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">throw</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">new</span><span style="color:rgb(0,0,0)"> AssertionError(</span><span style="color:rgb(106,62,62)">ex</span><span style="color:rgb(0,0,0)">);</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> }</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> }</span></p><p style="margin:0px"><br></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(63,95,191)">/// Allocate java stub for upcall</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">public</span><span style="color:rgb(0,0,0)"> MemorySegment allocate(FunctionInterface </span><span style="color:rgb(106,62,62)">javaImpl</span><span style="color:rgb(0,0,0)">, Arena </span><span style="color:rgb(106,62,62)">scope</span><span style="color:rgb(0,0,0)">) {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">return</span><span style="color:rgb(0,0,0)"> Linker.</span><span style="color:rgb(0,0,0);font-style:italic">nativeLinker</span><span style="color:rgb(0,0,0)">().upcallStub(</span><span style="color:rgb(0,0,192)">upcall</span><span style="color:rgb(0,0,0)">.bindTo(</span><span style="color:rgb(106,62,62)">javaImpl</span><span style="color:rgb(0,0,0)">), </span><span style="color:rgb(0,0,192)">descriptor</span><span style="color:rgb(0,0,0)">, </span><span style="color:rgb(106,62,62)">scope</span><span style="color:rgb(0,0,0)">);</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> }</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)"> }</span></p><p style="margin:0px"><br></p><p style="margin:0px">Worth considering?</p><p style="margin:0px"><br></p><p style="margin:0px">Duncan</p></div></div><br></div><div><br></div><div><br></div><div><br> </div></div>