C Callbacks

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

C Callbacks

Udo Schneider
All,

is there any way to create regular C-Callbacks from within GST? I need
some magic which provides a function pointer (to a block or method)
which I can pass to a C func as callback.

As far as I can see the underlying libffi supports this using
ffi_prep_closure_loc(). Is this already available in GST?

CU,

Udo



_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: C Callbacks

Paolo Bonzini-2
Udo Schneider wrote:
> All,
>
> is there any way to create regular C-Callbacks from within GST? I need
> some magic which provides a function pointer (to a block or method)
> which I can pass to a C func as callback.
>
> As far as I can see the underlying libffi supports this using
> ffi_prep_closure_loc(). Is this already available in GST?

No, but callbacks are available without using libffi.  You use functions
in the vm_proxy, see the GLUT bindings in the opengl branch of my
repository for a simple example.

Paolo


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: C Callbacks

Udo Schneider
Paolo,

> No, but callbacks are available without using libffi.  You use functions
> in the vm_proxy, see the GLUT bindings in the opengl branch of my
> repository for a simple example.
Nice examples! However as far as I see the callbacks are "static". The
callback functions are in C and in turn call Smalltalk methods via
vmproxy. What I was thinking of is defining a callback by providing a
method/block with appropriate arg and return types in Smalltalk
dynamically (something similar to ExternalCallbacks in Dolphin Smalltalk
http://www.object-arts.com/docs/externalcallbackobjects.htm)

E.g.
callback := ExternalCallback
       block: [ :lplf :lptm :dwType :lpData | operation value: lplf
value: lptm value: dwType ]
       argumentTypes: 'LOGFONT* lpvoid dword dword'.

Due to the fact that I need to create callbacks dynamically based on
third party data I get (dynamically as well :-( ) I think there is no
way around libffi. Maybe I can reuse the existing parameter stuff around
#cCall: for inbound calls.

Thanks,

Udo



_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: Re: C Callbacks

Paolo Bonzini-2
.
> callback := ExternalCallback
>       block: [ :lplf :lptm :dwType :lpData | operation value: lplf
> value: lptm value: dwType ]
>       argumentTypes: 'LOGFONT* lpvoid dword dword'

I see -- the most similar thing to this one is provided by msgSendf.
You would have to rewrite msgSendf as a function that follows the libffi
closure API, and then pass it to the ffi_prep_closure together with an
ffi_cif (there is already code to construct ffi_cif from a
CFunctionDescriptor).  See for example
http://developer.apple.com/documentation/Darwin/Reference/ManPages/man3/ffi_prep_closure.3.html 
(the main difference is that, in the example, foo_closure does not look
at its CIF argument).

> Due to the fact that I need to create callbacks dynamically based on
> third party data I get (dynamically as well :-( ) I think there is no
> way around libffi. Maybe I can reuse the existing parameter stuff around
> #cCall: for inbound calls.

Yes, most of it is written for libffi so it can be recycled for this
setting too.  It's in cint.c.

Paolo


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: C Callbacks

Paolo Bonzini-2
In reply to this post by Udo Schneider
> Maybe I can reuse the existing parameter stuff around
> #cCall: for inbound calls.

If you want to warm up with that code, you might start converting this
part of it to Smalltalk:

   desc->returnType = classify_type_symbol (returnTypeOOP, true);
   if (desc->returnType == _gst_nil_oop)
     goto error;

   for (i = 1; i <= numArgs; i++)
     {
       OOP type;
       type = desc->argTypes[i - 1] =
         classify_type_symbol (ARRAY_AT (argsOOP, i), false);
       if (type == _gst_nil_oop)
         goto error;
     }

... together with symbol_type_map, type_map, classify_type_symbol.

Paolo


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: C Callbacks

Paolo Bonzini-2
Paolo Bonzini wrote:

>> Maybe I can reuse the existing parameter stuff around #cCall: for
>> inbound calls.
>
> If you want to warm up with that code, you might start converting this
> part of it to Smalltalk:
>
>   desc->returnType = classify_type_symbol (returnTypeOOP, true);
>   if (desc->returnType == _gst_nil_oop)
>     goto error;
>
>   for (i = 1; i <= numArgs; i++)
>     {
>       OOP type;
>       type = desc->argTypes[i - 1] =
>         classify_type_symbol (ARRAY_AT (argsOOP, i), false);
>       if (type == _gst_nil_oop)
>         goto error;
>     }
>
> ... together with symbol_type_map, type_map, classify_type_symbol.

Actually, what I meant is that this code is duplicated in C and
Smalltalk (kernel/CFuncs.st).  It would be interesting to use only the
Smalltalk one.  To this end, the C primitive VMpr_CFuncDescriptor_create
(defined in prims.def and cint.c) should be simplified to just return
the address of a C function.  Everything else can be done in Smalltalk.

Paolo


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk