comp.lang.ada
 help / color / mirror / Atom feed
* How to import C pointers to structures?
@ 2014-05-19 22:26 Victor Porton
  2014-05-19 22:33 ` Shark8
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Victor Porton @ 2014-05-19 22:26 UTC (permalink / raw)


I've recently studied about the latest Ada standard (Ada2012) with the 
purpose to port librdf to Ada and then use it in my project.

Suppose we have a C function:

void f(struct_t *ptr);

Here struct_t is a typedef which denotes an structure which layout should be 
considered unknown to us.

How to import it to Ada? We don't know struct_t layout.

-- 
Victor Porton - http://portonvictor.org

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

* Re: How to import C pointers to structures?
  2014-05-19 22:26 How to import C pointers to structures? Victor Porton
@ 2014-05-19 22:33 ` Shark8
  2014-05-19 22:44   ` Adam Beneschan
  2014-05-20  8:29 ` björn lundin
  2014-05-20 19:07 ` Per Sandberg
  2 siblings, 1 reply; 9+ messages in thread
From: Shark8 @ 2014-05-19 22:33 UTC (permalink / raw)


On 19-May-14 16:26, Victor Porton wrote:
>
> How to import it to Ada? We don't know struct_t layout.

You generally *can't* do a real/meaningful import w/o knowing the 
layout. You /can/ have an importation of the pointer itself, though 
that's not particularly helpful w/o the structure; something like:

Type Structure_Stub is null record
with Convention => C;

Type Structure_Pointer is access Structure_Stub
with Convention => C;

------

I think.
I try to steer clear of C.


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

* Re: How to import C pointers to structures?
  2014-05-19 22:33 ` Shark8
@ 2014-05-19 22:44   ` Adam Beneschan
  2014-05-20  0:10     ` Shark8
  0 siblings, 1 reply; 9+ messages in thread
From: Adam Beneschan @ 2014-05-19 22:44 UTC (permalink / raw)


On Monday, May 19, 2014 3:33:56 PM UTC-7, Shark8 wrote:
> On 19-May-14 16:26, Victor Porton wrote:
> 
> > How to import it to Ada? We don't know struct_t layout.
> 
> You generally *can't* do a real/meaningful import w/o knowing the 
> layout. 

I'm not sure that's quite true ... there are lots of situations where you simply want to "pass through" a pointer, e.g. in callback situations, where a function sets up a callback and says "when you do the callback, please pass this pointer to it"; and whoever registers the callback will take the pointer, store it somewhere, and use it when it's needed, without ever trying to look at what it points to.

Unfortunately, I don't see the equivalent of "void *" anywhere in Interfaces.C, which is what the sort of thing you'd want.  You could probably use Interfaces.C.Strings.chars_ptr (the equivalent of "char *").  Your suggestion:

> You /can/ have an importation of the pointer itself, though 
> that's not particularly helpful w/o the structure; something like:
> 
> Type Structure_Stub is null record
> with Convention => C;
> 
> Type Structure_Pointer is access Structure_Stub
> with Convention => C;

should work too.

                                 -- Adam


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

* Re: How to import C pointers to structures?
  2014-05-19 22:44   ` Adam Beneschan
@ 2014-05-20  0:10     ` Shark8
  2014-05-20  0:22       ` Adam Beneschan
  0 siblings, 1 reply; 9+ messages in thread
From: Shark8 @ 2014-05-20  0:10 UTC (permalink / raw)


On 19-May-14 16:44, Adam Beneschan wrote:
>> You generally *can't*  do a real/meaningful import w/o knowing the
>> layout.
>
> I'm not sure that's quite true ... there are lots of situations
> where you simply want to "pass through" a pointer, e.g. in
> callback situations, where a function sets up a callback and says
> "when you do the callback, please pass this pointer to it"; and
> whoever registers the callback will take the pointer, store it
> somewhere, and use it when it's needed, without ever trying to
> look at what it points to.

While those are /common/ cases, I would be hesitant to call them 
/general/ cases.

> Unfortunately, I don't see the equivalent of "void *" anywhere in
> Interfaces.C, which is what the sort of thing you'd want.  You
> could probably use Interfaces.C.Strings.chars_ptr (the equivalent
> of "char *").

Instantiate Interfaces.C.Pointers on a null-record or, perhaps, 
System.Address?

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

* Re: How to import C pointers to structures?
  2014-05-20  0:10     ` Shark8
@ 2014-05-20  0:22       ` Adam Beneschan
  2014-05-20  6:36         ` Simon Wright
  0 siblings, 1 reply; 9+ messages in thread
From: Adam Beneschan @ 2014-05-20  0:22 UTC (permalink / raw)


On Monday, May 19, 2014 5:10:14 PM UTC-7, Shark8 wrote:
> On 19-May-14 16:44, Adam Beneschan wrote:
> 
> >> You generally *can't*  do a real/meaningful import w/o knowing the
> >> layout.
> 
> > I'm not sure that's quite true ... there are lots of situations
> > where you simply want to "pass through" a pointer, e.g. in
> > callback situations, where a function sets up a callback and says
> > "when you do the callback, please pass this pointer to it"; and
> > whoever registers the callback will take the pointer, store it
> > somewhere, and use it when it's needed, without ever trying to
> > look at what it points to.
> 
> While those are /common/ cases, I would be hesitant to call them 
> /general/ cases.
> 
> > Unfortunately, I don't see the equivalent of "void *" anywhere in
> > Interfaces.C, which is what the sort of thing you'd want.  You
> > could probably use Interfaces.C.Strings.chars_ptr (the equivalent
> > of "char *").
> 
> Instantiate Interfaces.C.Pointers on a null-record or, perhaps, 
> System.Address?

I wouldn't trust System.Address; there's no guarantee that the Ada implementation of this Ada type is represented the same way as a C pointer, an Ada access object, or anything else.  The first idea, to instantiate Interfaces.C.Pointers, should be trustworthy--that's an excellent idea.

                               -- Adam

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

* Re: How to import C pointers to structures?
  2014-05-20  0:22       ` Adam Beneschan
@ 2014-05-20  6:36         ` Simon Wright
  0 siblings, 0 replies; 9+ messages in thread
From: Simon Wright @ 2014-05-20  6:36 UTC (permalink / raw)


Adam Beneschan <adambeneschan@gmail.com> writes:

> I wouldn't trust System.Address; there's no guarantee that the Ada
> implementation of this Ada type is represented the same way as a C
> pointer, an Ada access object, or anything else

AdaCore have Interfaces.C.Extensions which has

   --  Definitions for C "void" and "void *" types

   subtype void     is System.Address;
   subtype void_ptr is System.Address;

   --  Definitions for C incomplete/unknown structs

   subtype opaque_structure_def is System.Address;
   type opaque_structure_def_ptr is access opaque_structure_def;
   for opaque_structure_def_ptr'Storage_Size use 0;

   --  Definitions for C++ incomplete/unknown classes

   subtype incomplete_class_def is System.Address;
   type incomplete_class_def_ptr is access incomplete_class_def;
   for incomplete_class_def_ptr'Storage_Size use 0;

but it's their compiler on both sides so they know it's OK!


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

* Re: How to import C pointers to structures?
  2014-05-19 22:26 How to import C pointers to structures? Victor Porton
  2014-05-19 22:33 ` Shark8
@ 2014-05-20  8:29 ` björn lundin
  2014-05-20 19:07 ` Per Sandberg
  2 siblings, 0 replies; 9+ messages in thread
From: björn lundin @ 2014-05-20  8:29 UTC (permalink / raw)


Den tisdagen den 20:e maj 2014 kl. 00:26:07 UTC+2 skrev Victor Porton:
 
> Suppose we have a C function:
> void f(struct_t *ptr);
> How to import it to Ada? We don't know struct_t layout.

I used a binding to Postgresql that I found a long time ago,
(by Samuel Tardieu), that declares this:

   type Pg_Conn is null record;
   type Pg_Conn_Access is access Pg_Conn;
   pragma Convention (C, Pg_Conn_Access);

   type Pg_Result is null record;
   type Pg_Result_Access is access Pg_Result;
   pragma Convention (C, Pg_Result_Access);


To get a pointer to the db_connection object you use

   function PQ_Connectdb (Conn_Info : Chars_Ptr) return Pg_Conn_Access;
   pragma Import (C, PQ_Connectdb, "PQconnectdb");
   

and then use it to get result sets
   function Pq_Exec (Conn  : Pg_Conn_Access;
                     Query : Chars_Ptr)
                     return Pg_Result_Access;
   pragma Import (C, Pq_Exec, "PQexec");


So, you do not need to know the underlaying structure,
only to pass the pointer around.


-- 
Björn Lundin

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

* Re: How to import C pointers to structures?
  2014-05-19 22:26 How to import C pointers to structures? Victor Porton
  2014-05-19 22:33 ` Shark8
  2014-05-20  8:29 ` björn lundin
@ 2014-05-20 19:07 ` Per Sandberg
  2014-05-22 13:37   ` Stephen Leake
  2 siblings, 1 reply; 9+ messages in thread
From: Per Sandberg @ 2014-05-20 19:07 UTC (permalink / raw)



Well
given that you are runnig a fairly GCC all the answers is in the compiler.

$echo "#include <your_interface.h>" >gen.cpp
$g++ -c -fdump-ada-spec gen.cpp
then you will get correct mapping:
your_interface.h <=> your_interface_h.ads

See:

https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gnat_ugn_unw/Running-the-binding-generator.html#Running-the-binding-generator
for more information.

To "generate" interfaces in any other way is inherently error-prone 
since humans tend to miss a lot of details.


/Per

On 20.05.2014 00:26, Victor Porton wrote:
> I've recently studied about the latest Ada standard (Ada2012) with the
> purpose to port librdf to Ada and then use it in my project.
>
> Suppose we have a C function:
>
> void f(struct_t *ptr);
>
> Here struct_t is a typedef which denotes an structure which layout should be
> considered unknown to us.
>
> How to import it to Ada? We don't know struct_t layout.
>


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

* Re: How to import C pointers to structures?
  2014-05-20 19:07 ` Per Sandberg
@ 2014-05-22 13:37   ` Stephen Leake
  0 siblings, 0 replies; 9+ messages in thread
From: Stephen Leake @ 2014-05-22 13:37 UTC (permalink / raw)


Per Sandberg <per.s.sandberg@bahnhof.se> writes:

> $echo "#include <your_interface.h>" >gen.cpp
> $g++ -c -fdump-ada-spec gen.cpp
> then you will get correct mapping:
> your_interface.h <=> your_interface_h.ads
>
> See:
>
> https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gnat_ugn_unw/Running-the-binding-generator.html#Running-the-binding-generator
> for more information.
>
> To "generate" interfaces in any other way is inherently error-prone
> since humans tend to miss a lot of details.

And it can be included in makefiles, so when the .h changes due to an
update, the .ads changes as well.


-- 
-- Stephe

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

end of thread, other threads:[~2014-05-22 13:37 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-19 22:26 How to import C pointers to structures? Victor Porton
2014-05-19 22:33 ` Shark8
2014-05-19 22:44   ` Adam Beneschan
2014-05-20  0:10     ` Shark8
2014-05-20  0:22       ` Adam Beneschan
2014-05-20  6:36         ` Simon Wright
2014-05-20  8:29 ` björn lundin
2014-05-20 19:07 ` Per Sandberg
2014-05-22 13:37   ` Stephen Leake

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