comp.lang.ada
 help / color / mirror / Atom feed
* Dispatching callback handed over to C
@ 2012-04-03  7:19 Natasha Kerensikova
  2012-04-03  9:04 ` Brian Drummond
  2012-04-03  9:37 ` Maciej Sobczak
  0 siblings, 2 replies; 25+ messages in thread
From: Natasha Kerensikova @ 2012-04-03  7:19 UTC (permalink / raw)


Hello,

I'm wondering whether I'm calling on you too much, so please tell me
when I'm abusing the resource that comp.lang.ada is and/or your time.

The problem I'm facing currently is binding to a very common idiom for
callback in C. There a setup function that expects a pointer to a
function and a pointer to opaque data, that will be given as-is to the
pointed function.

On the Ada side, it seemed to be a perfect use case for tagged types. I
still haven't decided between a dedicated interface with a single
method, or add an abstract method in the tagged type that handles the C
structure where the callback reference is stored.

It would be wonderful if there was a way to "pre-dispatch" the call,
i.e. giving to the C library the address of the actual subprogram
called. The information has to be available at this point, since it's
the address called if I went for a real dispatching call at this point.
However I have no idea what the syntax would look like, or how it could
be type-checked (since one of the parameters of that subprogram would be
of the same as the actual type of the class-wide variable, which is not
known at compile-time). But since we're interfacing with C, we're
expecting all sorts of type-check trouble anyway.

So, is there any way to get the address where a dispatching call would
lead?



I tried to work around it, by having a single dedicated callback
subprogram given to the C library, and interfacing C « void* » with
access Event_Callback'Class. So that the body of the dedicated callback
is only a dispatching call. It's a waste of code lines and calling
sequence, but I guess bindings are never optimal.

I was stopped by the following warning from GNAT:
        >>> warning: "Event_New.Arg" involves a tagged type which does
not correspond to any C type
And I can't decipher it. I tried with various access-type naming and
pragma Convention, but I couldn't make it disappear.

Of course, it's only a warning, so I could just ignore it. However
I'm comfortable with ignoring warnings only when I actually know they
don't warn about any real danger in the particular situation. This is
far from being the case, since I don't really understand what is going
on.



On top of all that, I wanted to add some safety mechanisms, to prevent
the callback from disappearing while still being referred to.

One possibility is to make the callback part of the type that handles
the C structure where it is stored. That structure is freed in
Finalize, so references to the callback object are cleaned up when the
both are destroyed.

However, since it deals with opaque C pointers that cannot be
duplicated, it has to be limited. This makes a lot of things unnecessary
difficult for the callback part.

Moreover, some applications might want to attach the same callback to
multiple structure (since the C structure is tied to a lot of other
thins, like a socket FD and an event mask, so it might make sense to
have several of these for the same underlying callback code and state).

So I thought of access discriminants: if I understand correctly, there
is some compile-time check to ensure the lifetime of the accessed object
(i.e. the callback) is at least as long as that of the discriminated
object (i.e. the C structure).

However, I can't seem to properly hand it over to the C function:
when I use an anonymous access type, I get a convention error, and when
I use a named access type (with pragma Convention), I cannot convert
the discriminant to it.



I'm really surprised to find so little information about this problem,
considering how often I saw the idiom during my C days. I also tried a
few existing bindings, like Claw, but couldn't find any precedent either
(I admit I have not looked in Qt or Gtk bindings, but I'm afraid it
would take too much time to understand what is going on before I could
mimic it (I have never coded for Qt or Gtk in my life)).


Thanks in advance for your help, and sorry to so annoying for you,
Natasha



^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2012-04-10  7:15 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-03  7:19 Dispatching callback handed over to C Natasha Kerensikova
2012-04-03  9:04 ` Brian Drummond
2012-04-03  9:21   ` Thomas Locke
2012-04-03  9:37 ` Maciej Sobczak
2012-04-03 12:02   ` Natasha Kerensikova
2012-04-03 14:42     ` Maciej Sobczak
2012-04-03 20:20       ` Randy Brukardt
2012-04-04  7:26         ` Georg Bauhaus
2012-04-04  7:56         ` Natasha Kerensikova
2012-04-04 19:28           ` Randy Brukardt
2012-04-05  8:59             ` Natasha Kerensikova
2012-04-05 21:04               ` Randy Brukardt
2012-04-04 19:55           ` Simon Wright
2012-04-04 11:34         ` Maciej Sobczak
2012-04-04 19:16           ` Randy Brukardt
2012-04-05  7:28             ` Maciej Sobczak
2012-04-05 21:32               ` Randy Brukardt
2012-04-07  8:55                 ` Natasha Kerensikova
2012-04-07 11:32                   ` Simon Wright
2012-04-07 13:28                     ` Robert A Duff
2012-04-05  9:13             ` Natasha Kerensikova
2012-04-05 21:06               ` Randy Brukardt
2012-04-06  7:30               ` Maciej Sobczak
2012-04-06 11:41                 ` Simon Wright
2012-04-10  7:15                   ` Maciej Sobczak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox