Binding a single function symbol with [foreign]
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Thu Sep 6 17:42:11 UTC 2018
Hi Jorn,
thanks for your feedback and your interest in our 'foreign' development.
The issue you bring up is a very good one - that is, the target of a
binding is, currently, an interface. But one might envision (as you did)
cases where maybe you just want a single method handle to be the result
of your bind.
This is technically possible - after all, this is what our binder does
internally (see NativeInvoker). To get there you need 2 ingredients:
1) the method type you want to use for the call
2) the layout of the function parameters/return type
Now, as I type this I realize that there's a third ingredient that is
present in sources, but missing in this formulation:
3) the generic signatures of arguments/return types - this is a crucial
piece to tell the binder whether the result should be a Pointer<Byte>
vs. Pointer<Integer> and so forth; note that this is more than just
static typing: a Pointer<Integer> will carry runtime type information of
the fact that it points to an Integer memory region (with given layout -
e.g. i32).
That said, we could, in principle, use (2) to infer the same information
available in (3) - e.g. if the method type says it returns a
Pointer.class and the layout says u64:i32, we could then infer
Pointer<Integer>. It seems doable.
After you have (1), (2) and (3) you are finally in the position to
create a method handle for your native function.
So yes, we could have, in principle a method on Symbol like this:
MethodHandle bindAsFunction(MethodType, Function)
And probably another pair:
MethodHandle bindAsVarGetter(Class<?>, Layout)
MethodHandle bindAsVarSetter(Class<?>, Layout)
(since treatment for functions is different from that of global variables).
Would this be something like this useful to the use case you have in mind?
Cheers
Maurizio
On 06/09/18 14:49, Jorn Vernee wrote:
> Hello,
>
> I was checking out the [foreign] branch today to see what was
> currently possible with it. I have been following the mailing list for
> a while now, and it's always very interesting to read the emails
> discussing the development of this project (especially the technical
> details).
>
> It seems that currently the only way to bind a native library is to
> bind the entire library to a Java artifact, like one that is generated
> by jextract, through a call to `Libraries.bind`.
>
> The usage I was looking for was more like this:
>
> Library lib = Libraries.loadLibrary(lookup(), "msvcrt");
>
> Symbol printf = lib.lookup("printf"); // possibly need mangled
> name here?
> // imaginary api:
> MethodHandle mh = ((FunctionSymbol) printf).bind(); // Or,
> manually provide layout information to bind?
> Scope scope = Scope.newNativeScope();
> Pointer<Byte> message = scope.toCString("Hello World!");
> int result = (int) mh.invokeExact(message);
>
> i.e. having the ability to bind a single function symbol from some
> library and then being able to call that function, without the need to
> use a tool like jextract and binding the generated artifact.
>
> Do you think also having a more low-level API like this is
> possible/desirable?
>
> Best regards,
> Jorn Vernee
More information about the panama-dev
mailing list