From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.9 required=5.0 tests=BAYES_00,FORGED_GMAIL_RCVD, FREEMAIL_FROM autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,73975695cdfcb86f,start X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,UTF8 Received: by 10.68.236.170 with SMTP id uv10mr8690397pbc.4.1333437597592; Tue, 03 Apr 2012 00:19:57 -0700 (PDT) Path: r9ni12868pbh.0!nntp.google.com!news1.google.com!goblin2!goblin.stu.neva.ru!newsfeed1.swip.net!85.214.198.2.MISMATCH!eternal-september.org!feeder.eternal-september.org!mx04.eternal-september.org!.POSTED!not-for-mail From: Natasha Kerensikova Newsgroups: comp.lang.ada Subject: Dispatching callback handed over to C Date: Tue, 3 Apr 2012 07:19:56 +0000 (UTC) Organization: A noiseless patient Spider Message-ID: Mime-Version: 1.0 Injection-Date: Tue, 3 Apr 2012 07:19:56 +0000 (UTC) Injection-Info: mx04.eternal-september.org; posting-host="Mda950WjNwNLAFOE7yJXQw"; logging-data="13029"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19jl1uXpOIo7zDf6IB8r+X9" User-Agent: slrn/0.9.9p1 (FreeBSD) Cancel-Lock: sha1:ePqzdxsAu3DGCV8w+YHwiJukhu8= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Date: 2012-04-03T07:19:56+00:00 List-Id: 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