comp.lang.ada
 help / color / mirror / Atom feed
From: Natasha Kerensikova <lithiumcat@gmail.com>
Subject: Re: Dispatching callback handed over to C
Date: Thu, 5 Apr 2012 09:13:10 +0000 (UTC)
Date: 2012-04-05T09:13:10+00:00	[thread overview]
Message-ID: <slrnjnqoga.1lme.lithiumcat@sigil.instinctive.eu> (raw)
In-Reply-To: jli6n9$5up$1@munin.nbi.dk

On 2012-04-04, Randy Brukardt <randy@rrsoftware.com> wrote:
> For instance, that's how we find the Ada object in Claw; we 
> unchecked-convert access-to-class-wide to a DWord in Windows, and then when 
> we need to use it, we unchecked-convert back. If I needed to make this 
> totally portable and had sufficient control over the API, I'd replace the 
> DWord by a locally-declared modular type of which I could control the size 
> to match the target. But there is little point in going further than that.
>
> System.Address is the wrong type to use for a "bucket-of-bits". I agree that 
> it would be nice to be able to directly put the access-to-class-wide in the 
> C convention record (and most compilers will in fact allow this, after 
> giving some warnings), but it doesn't seem to make that much difference.

So for my binding, what about something like :

   type Opaque_Data is null record;
   pragma Convention (C, Opaque_Data);

   type Opaque_Pointer is access all Opaque_Data;
   pragma Convention (C, Opaque_Pointer);

   type Callback_Access is access all Event_Callback'Class;
   pragma Convention (C, Callback_Access);

   procedure Set_C_Callback (<various arguments>;
                             Data : Opaque_Pointer);
   pragma Import (C, Set_C_Callback, "set_callback");


   procedure Called_From_C (<various arguments>;
                            Data : Opaque_Pointer)
   is
      package To_Ada is new Ada.Unchecked_Conversion
        (Source => Opaque_Pointer, Target => Callback_Access);

      Callback : Callback_Access := To_Ada (Data);
   begin
      Callback.all.Handle (<...>);
   end Called_From_C;

   pragma Convention (C, Called_From_C);


   procedure Set_Callback (<various arguments>;
                           Callback : in out Event_Callback'Class)
   is
      package To_C is new Ada.Unchecked_Conversion
        (Source => Callback_Access, Target => Opaque_Pointer);
   begin
      Set_C_Callback (<...>, To_C (Callback'Access));
   end Set_Callback;

As far as I cen tell, Opaque_Pointer refers only to types compatibles
with C, so the imports goes well and without warning, while
Opaque_Pointer and Callback_Access, being both access types with the
same convention, ensures they can be safely (in terms of keeping the
bit pattern intact, of course not type-safety) converted back and forth.

Or is there some trap in the above code that I'm missing?


Thanks for your help,
Natasha



  parent reply	other threads:[~2012-04-05  9:13 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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
replies disabled

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