comp.lang.ada
 help / color / mirror / Atom feed
* Importing C structs?
@ 2003-07-30 20:03 Freejack
  2003-07-30 20:52 ` chris
                   ` (2 more replies)
  0 siblings, 3 replies; 28+ messages in thread
From: Freejack @ 2003-07-30 20:03 UTC (permalink / raw)


I'm finally starting to get an idea(at least I think I am.) on handling
interfacing to C.

However, I'm fuzzy on importing C structs. In a nutshell...here is the
function I'm attempting to import...

	DB *
	  dbopen(const char *file, int flags, int mode, DBTYPE type,
		const void *openinfo);


Where "int mode" corresponds to the C "open" declaration and DBTYPE is a
C struct. I'm using the dbopen man page for the Sleepycat Berkely DB.

Now I'm using

	pragma Import( C, dbopen );
	
And then casting everything as either a C.integer or a character pointer.
 It compiles this way, but it sucks as a way to do it.

Specifically, would I cast DBTYPE as a seperate record type, and then
provide a seperate function to translate each item into the type expected
by the C struct? Or can import the DBTYPE struct whole hog into my Ada
specification?

Note, you'll need the SleepyCat Berkely DB header file db.h in order to
see what I'm referring to.

I've gained some skills in working strictly with the Ada environment. But
Interfacing with C is gonna take me a little while longer to learn.

Thanks for any pointers.


Freejack



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

* Re: Importing C structs?
  2003-07-30 20:03 Importing C structs? Freejack
@ 2003-07-30 20:52 ` chris
  2003-07-30 21:26   ` Freejack
                     ` (3 more replies)
  2003-07-30 23:14 ` Ching Bon Lam
  2003-07-31  5:21 ` Matthew Heaney
  2 siblings, 4 replies; 28+ messages in thread
From: chris @ 2003-07-30 20:52 UTC (permalink / raw)


Freejack wrote:
> I'm finally starting to get an idea(at least I think I am.) on handling
> interfacing to C.

Really?  I don't think I'll ever get the hang of it.

> Specifically, would I cast DBTYPE as a seperate record type, and then
> provide a seperate function to translate each item into the type expected
> by the C struct? Or can import the DBTYPE struct whole hog into my Ada
> specification?

Make an Ada record corresponding to that type.  Map it's fields to 
things from interfaces.c and other records.  Then use

pragma Convention(C, DBType);

I think!

This is from my ongoing work on a libjpeg binding...

    type Jpeg_Error_Mgr is record
       Error_Exit          : Error_Exit_Handler;
       Emit_Message        : Emit_Message_Handler;
       Output_Message      : Output_Message_Handler;
       Format_Message      : Format_Message_Handler;
       Reset_Error_Mgr     : Reset_Error_Handler;
       Msg_Code            : C.Int;
       Msg_Parm            : System.Address;
       Trace_Level         : C.Int;
       Num_Warnings        : C.Long;
       Jpeg_Message_Table  : Jpeg_Message_TableT;
       Last_Jpeg_Message   : C.Int;
       Addon_Message_Table : Jpeg_Message_TableT;
       First_Addon_Message : C.Int;
       Last_Addon_Message  : C.Int;
    end record;

    pragma Convention (C, Jpeg_Error_Mgr);


HTH,
Chris




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

* Re: Importing C structs?
  2003-07-30 20:52 ` chris
@ 2003-07-30 21:26   ` Freejack
  2003-07-30 23:50   ` tmoran
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 28+ messages in thread
From: Freejack @ 2003-07-30 21:26 UTC (permalink / raw)


On Wed, 30 Jul 2003 16:52:49 -0400, chris wrote:

 
> Make an Ada record corresponding to that type.  Map it's fields to
> things from interfaces.c and other records.  Then use
> 
> pragma Convention(C, DBType);
> 
> I think!
> 
> This is from my ongoing work on a libjpeg binding...
> 
>     type Jpeg_Error_Mgr is record
>        Error_Exit          : Error_Exit_Handler; Emit_Message        :
>        Emit_Message_Handler; Output_Message      :
>        Output_Message_Handler; Format_Message      :
>        Format_Message_Handler; Reset_Error_Mgr     :
>        Reset_Error_Handler; Msg_Code            : C.Int; Msg_Parm       
>            : System.Address; Trace_Level         : C.Int;
>        Num_Warnings        : C.Long;
>        Jpeg_Message_Table  : Jpeg_Message_TableT; Last_Jpeg_Message   :
>        C.Int;
>        Addon_Message_Table : Jpeg_Message_TableT; First_Addon_Message :
>        C.Int;
>        Last_Addon_Message  : C.Int;
>     end record;
> 
>     pragma Convention (C, Jpeg_Error_Mgr);
 
 
> HTH,
> Chris
 
I've been toying with the idea of creating a generic procedure for these
types of situations. I dont know if Ada will let me get away with it
though.

i.e.

with Interfaces.C;
with Interfaces.C....blah blah blah;

generic
	type foo is new private(<>);
	type bar is new private(<>);
package dooh_dah is

	package Some_C renames Interfaces.C.blah;

private

	function cast_to_C(foo : in Ada_Type) return Is_Success;
	
	-- etc..etc..etc...
	
end dooh_dah;

Now, I realize that the Interfaces library provides a limited set of
functions and procedures for performing some of the operations I'm
talking about here. But as far as I know everything has to be set up
explicitly. I'm hoping theres a way to have the compiler do an automatic
cast (or export) to a C function depending the execution context.

But that type of programming is a little ways down the road. I dont have
a need for this yet, but maybe later.

Freejack.



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

* Re: Importing C structs?
  2003-07-30 20:03 Importing C structs? Freejack
  2003-07-30 20:52 ` chris
@ 2003-07-30 23:14 ` Ching Bon Lam
  2003-07-31  0:07   ` tmoran
  2003-07-31  5:35   ` Matthew Heaney
  2003-07-31  5:21 ` Matthew Heaney
  2 siblings, 2 replies; 28+ messages in thread
From: Ching Bon Lam @ 2003-07-30 23:14 UTC (permalink / raw)


Freejack <freejack@nospam.net> wrote in 
news:pan.2003.07.30.20.09.17.183172.1022@nospam.net:

> I'm finally starting to get an idea(at least I think I am.) on handling
> interfacing to C.

just a process of trial&error.. very time consuming.

> 
> However, I'm fuzzy on importing C structs. In a nutshell...here is the
> function I'm attempting to import...
> 
>      DB *
>        dbopen(const char *file, int flags, int mode, DBTYPE type,
>           const void *openinfo);

that would be:

type DB is interfaces.c.extensions.opaque_structure_def;

-- i have too less information about DBTYPE, so i assume
-- it's just a struct
type DBTYPE is interfaces.c.extensions.opaque_structure_def;

function dbopen
   (file     : interfaces.c.char_array;
    flags    : interfaces.c.int;
    mode     : interfaces.c.int;
    type     : DBTYPE;
    openinfo : interfaces.c.extensions.void_ptr)
   return DB;

pragma Import(C, dbopen, "dbopen');

hope this works..

CBL



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

* Re: Importing C structs?
  2003-07-30 20:52 ` chris
  2003-07-30 21:26   ` Freejack
@ 2003-07-30 23:50   ` tmoran
  2003-07-31 10:53     ` chris
  2003-08-04 14:33     ` Andreas Almroth
  2003-07-31 17:14   ` Warren W. Gay VE3WWG
  2003-07-31 18:17   ` Xenos
  3 siblings, 2 replies; 28+ messages in thread
From: tmoran @ 2003-07-30 23:50 UTC (permalink / raw)


>   type Jpeg_Error_Mgr is record
>      ...
>      Msg_Parm            : System.Address;

  This is wrong.  The C has

>   union {
>     int i[8];
>     char s[JMSG_STR_PARM_MAX];
>   } msg_parm;
  which means msg_parm is JMSG_STR_PARM_MAX number of bytes, interpretable
sometimes as a char array and sometimes as an int array followed by
filler.  msg_parm is never an address.  To match the C, I suggest making
msg_parm an interfaces.c.char_array (the larger of the two objects),
and then doing an unchecked_conversion on those (relatively rare)
occasions when you need to treat it as an array of int's.  Here's
a compilable example:

with interfaces.c;
with ada.unchecked_conversion;
procedure testluc is

  JMSG_STR_PARM_MAX: constant := 80;
  subtype Msg_Parm_C_Type is Interfaces.C.Char_Array(1 .. JMSG_STR_PARM_MAX);

  subtype I_Part is Interfaces.C.Size_T range 1 .. 32;
  subtype Msg_Parm_C_I_Part is Interfaces.C.Char_Array(I_Part);
  type Msg_Parm_I_Type is array(1 .. 8) of Interfaces.C.Int;

  function To_I is new Ada.Unchecked_Conversion
    (Source=>Msg_Parm_C_I_Part,
     Target=>Msg_Parm_I_Type);

  function To_C is new Ada.Unchecked_Conversion
    (Source=>Msg_Parm_I_Type,
     Target=>Msg_Parm_C_I_Part);

  type Jpeg_Error_Mgr is record
    msg_parm: Msg_Parm_C_Type;
  end record;

  X : Jpeg_Error_Mgr;
  X_I : Msg_Parm_I_Type;
  N : Interfaces.C.Int;

begin
  -- fetch ints from X.msg_parm
  N := To_I(X.msg_parm(I_Part))(1);
  N := To_I(X.msg_parm(I_Part))(2);
  -- store ints into X.msg_parm
  X_I(1) := 1;
  X_I(8) := 2;
  X.msg_parm(I_Part):=To_C(X_I);
end testluc;



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

* Re: Importing C structs?
  2003-07-30 23:14 ` Ching Bon Lam
@ 2003-07-31  0:07   ` tmoran
  2003-07-31  5:35   ` Matthew Heaney
  1 sibling, 0 replies; 28+ messages in thread
From: tmoran @ 2003-07-31  0:07 UTC (permalink / raw)


> >      DB *
> >        dbopen(const char *file, int flags, int mode, DBTYPE type,
> >           const void *openinfo);
>
> type DB is interfaces.c.extensions.opaque_structure_def;
> function dbopen
>    return DB;
  Oops.  It returns an access to DB, not a DB.
And where does this interfaces.c.extensions come from?



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

* Re: Importing C structs?
  2003-07-30 20:03 Importing C structs? Freejack
  2003-07-30 20:52 ` chris
  2003-07-30 23:14 ` Ching Bon Lam
@ 2003-07-31  5:21 ` Matthew Heaney
  2 siblings, 0 replies; 28+ messages in thread
From: Matthew Heaney @ 2003-07-31  5:21 UTC (permalink / raw)



"Freejack" <freejack@nospam.net> wrote in message
news:pan.2003.07.30.20.09.17.183172.1022@nospam.net...
>
> However, I'm fuzzy on importing C structs. In a nutshell...here is the
> function I'm attempting to import...
>
> DB *
>   dbopen(const char *file, int flags, int mode, DBTYPE type,
> const void *openinfo);

type DB_Type is limited null record;
type DB_Access is access all DB_Type;
for DB_Access'Storage_Size use 0;
pragma Convention (C, DB_Access);

function dbopen
  (file : Interfaces.C.chars_ptr;
   flags : Interfaces.C.int;
   mode : Interfaces.C.int;
   dbtype : dbtype_type; --???
   openinfo : System.Address) return DB_Access;

pragma Convention (C, dbopen);
pragma Import (C, dbopen, "dbopen");


> Where "int mode" corresponds to the C "open" declaration and DBTYPE is a
> C struct. I'm using the dbopen man page for the Sleepycat Berkely DB.

I don't have the man pages available to me.  What exactly is DBTYPE?  Is
this a struct?  Is is really passed by value?

> Now I'm using
>
> pragma Import( C, dbopen );
>
> And then casting everything as either a C.integer or a character pointer.
>  It compiles this way, but it sucks as a way to do it.

Your pragma is OK, but I don't know why you're casting.

You can probably substitute type Standard.Integer for C.int, but this isn't
guaranteed to work.  (It does on GNAT, because GNAT guarantees that the Ada
representation matches the C representation.)

The example above is a thin binding.  You can always wrap that in
higher-level ("thick") call, inlined as desired.

> Specifically, would I cast DBTYPE as a seperate record type, and then
> provide a seperate function to translate each item into the type expected
> by the C struct? Or can import the DBTYPE struct whole hog into my Ada
> specification?

Import the struct.  But do post what the C struct looks like.





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

* Re: Importing C structs?
  2003-07-30 23:14 ` Ching Bon Lam
  2003-07-31  0:07   ` tmoran
@ 2003-07-31  5:35   ` Matthew Heaney
  2003-07-31  7:46     ` Freejack
  2003-07-31 11:29     ` Ching Bon Lam
  1 sibling, 2 replies; 28+ messages in thread
From: Matthew Heaney @ 2003-07-31  5:35 UTC (permalink / raw)



"Ching Bon Lam" <c.lam_REMOVE_THIS@student.utwente.nl> wrote in message
news:Xns93C9C9EB630Fcblamstudentutwenten@194.109.133.20...
>
> that would be:
>
> type DB is interfaces.c.extensions.opaque_structure_def;

This is probably overkill.  For an opaque type all you need to do is:

type DB_Type is limited null record;
type DB_Access is access all DB_Type;
for DB_Access'Storage_Size use 0;
pragma Convention (C, DB_Access);


> -- i have too less information about DBTYPE, so i assume
> -- it's just a struct
> type DBTYPE is interfaces.c.extensions.opaque_structure_def;
>
> function dbopen
>    (file     : interfaces.c.char_array;
>     flags    : interfaces.c.int;
>     mode     : interfaces.c.int;
>     type     : DBTYPE;
>     openinfo : interfaces.c.extensions.void_ptr)
>    return DB;
>
> pragma Import(C, dbopen, "dbopen');

The type of parameter file is incorrect.  The char_array type is an
unconstrained Ada array type, which does not correspond directly to any C
type.  Specifically, your problem is that on the Ada side a dope vector
describing the array object is passed -- this is definitely *not* what you
want.

You need to use the type Interfaces.C.Strings.chars_ptr instead.

You can probably use System.Address for void*. The C type void* was
accidently omitted from Interfaces.C in the Ada95 standard, but I assume
that oversite will be corrected in a future version of the language.

It's not clear whether your return type should be DB or an explicit access
type (as in DB_Access), because I'm not familiar with the package
Interfaces.C.extensions.  I would use DB_Access, which is completely
portable.

The type DBTYPE is a bit of a mystery at this point, since structs aren't
typically passed by value in C.  Perhaps DBTYPE is really a pointer?






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

* Re: Importing C structs?
  2003-07-31  5:35   ` Matthew Heaney
@ 2003-07-31  7:46     ` Freejack
  2003-07-31  9:27       ` Martin Dowie
  2003-07-31 17:34       ` Matthew Heaney
  2003-07-31 11:29     ` Ching Bon Lam
  1 sibling, 2 replies; 28+ messages in thread
From: Freejack @ 2003-07-31  7:46 UTC (permalink / raw)


On Thu, 31 Jul 2003 01:35:57 -0400, Matthew Heaney wrote:

> The type DBTYPE is a bit of a mystery at this point, since structs
> aren't typically passed by value in C.  Perhaps DBTYPE is really a
> pointer?

The header file declares it thusly....

/*******************************************************
 * Access methods.
 *******************************************************/
/*
 * !!!
 * Changes here must be reflected in java/src/com/sleepycat/db/Db.java.
 */
	typedef enum {
	DB_BTREE=1,
	DB_HASH,
	DB_RECNO,
	DB_QUEUE,
	DB_UNKNOWN			/* Figure it out on open. */
	} DBTYPE;
 
So I'm assuming I could just use an Ada enumerated type. (It compiles when I
do this, but it fails at runtime.)

The second hurdle I'll need to jump is creating a suitable Ada
replacement for this buttload of defines that occur after the DBTYPE
declaration.

/*
 * DB access method and cursor operation values.  Each value is an operation
 * code to which additional bit flags are added.
 */
#define	DB_AFTER	 1		/* c_put() */
#define	DB_APPEND	 2		/* put() */
#define	DB_BEFORE	 3		/* c_put() */
#define	DB_CACHED_COUNTS 4		/* stat() */
#define	DB_CHECKPOINT	 5		/* log_put(), log_get() */
#define	DB_CONSUME	 6		/* get() */
#define	DB_CONSUME_WAIT  7		/* get() */
#define	DB_CURLSN	 8		/* log_put() */
#define	DB_CURRENT	 9		/* c_get(), c_put(), log_get() */
#define	DB_FIRST	10		/* c_get(), log_get() */
#define	DB_FLUSH	11		/* log_put() */
#define	DB_GET_BOTH	12		/* get(), c_get() */
#define	DB_GET_BOTHC	13		/* c_get() (internal) */
#define	DB_GET_RECNO	14		/* c_get() */
#define	DB_JOIN_ITEM	15		/* c_get(); do not do primary lookup */
#define	DB_KEYFIRST	16		/* c_put() */
#define	DB_KEYLAST	17		/* c_put() */
#define	DB_LAST		18		/* c_get(), log_get() */
#define	DB_NEXT		19		/* c_get(), log_get() */
#define	DB_NEXT_DUP	20		/* c_get() */
#define	DB_NEXT_NODUP	21		/* c_get() */
#define	DB_NODUPDATA	22		/* put(), c_put() */
#define	DB_NOOVERWRITE	23		/* put() */
#define	DB_NOSYNC	24		/* close() */
#define	DB_POSITION	25		/* c_dup() */
#define	DB_POSITIONI	26		/* c_dup() (internal) */
#define	DB_PREV		27		/* c_get(), log_get() */
#define	DB_PREV_NODUP	28		/* c_get(), log_get() */
#define	DB_RECORDCOUNT	29		/* stat() */
#define	DB_SET		30		/* c_get(), log_get() */
#define	DB_SET_RANGE	31		/* c_get() */
#define	DB_SET_RECNO	32		/* get(), c_get() */
#define	DB_WRITECURSOR	33		/* cursor() */
#define	DB_WRITELOCK	34		/* cursor() (internal) */

But one step at a time.

Hooking into glibc is cake, but this is something else entirely. Heh.

Any suggestions?

Freejack



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

* Re: Importing C structs?
  2003-07-31  7:46     ` Freejack
@ 2003-07-31  9:27       ` Martin Dowie
  2003-07-31 21:41         ` Freejack
  2003-07-31 17:34       ` Matthew Heaney
  1 sibling, 1 reply; 28+ messages in thread
From: Martin Dowie @ 2003-07-31  9:27 UTC (permalink / raw)


"Freejack" <freejack@nospam.net> wrote in message
news:pan.2003.07.31.07.52.36.94842.845@nospam.net...
> So I'm assuming I could just use an Ada enumerated type. (It compiles when
I
> do this, but it fails at runtime.)

Note that the first underlying value is '1' not '0' and you should still
add a 'pragma Convention' to it.


> The second hurdle I'll need to jump is creating a suitable Ada
> replacement for this buttload of defines that occur after the DBTYPE
> declaration.
>
> /*
>  * DB access method and cursor operation values.  Each value is an
operation
>  * code to which additional bit flags are added.
>  */
> #define DB_AFTER 1 /* c_put() */
[snip]
> #define DB_WRITELOCK 34 /* cursor() (internal) */
>
> But one step at a time.
>
> Hooking into glibc is cake, but this is something else entirely. Heh.
>
> Any suggestions?

Get a C->Ada converter! c2ada springs to mind
http://www.averstar.com/~stt/bindings/c2ada/c2ada.html








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

* Re: Importing C structs?
  2003-07-30 23:50   ` tmoran
@ 2003-07-31 10:53     ` chris
  2003-08-04 14:33     ` Andreas Almroth
  1 sibling, 0 replies; 28+ messages in thread
From: chris @ 2003-07-31 10:53 UTC (permalink / raw)


tmoran@acm.org wrote:
> 
>   This is wrong.  The C has
> 
> 
>>  union {
>>    int i[8];
>>    char s[JMSG_STR_PARM_MAX];
>>  } msg_parm;
> 
>   which means msg_parm is JMSG_STR_PARM_MAX number of bytes, interpretable
> sometimes as a char array and sometimes as an int array followed by
> filler.  msg_parm is never an address.  To match the C, I suggest making
> msg_parm an interfaces.c.char_array (the larger of the two objects),
> and then doing an unchecked_conversion on those (relatively rare)
> occasions when you need to treat it as an array of int's.  

Yeah I knew that was wrong, I just didn't know what to map a union to 
and hadn't fixed it yet...  thanks for the example!


Thanks,
Chris




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

* Re: Importing C structs?
  2003-07-31  5:35   ` Matthew Heaney
  2003-07-31  7:46     ` Freejack
@ 2003-07-31 11:29     ` Ching Bon Lam
  2003-07-31 16:59       ` Matthew Heaney
                         ` (2 more replies)
  1 sibling, 3 replies; 28+ messages in thread
From: Ching Bon Lam @ 2003-07-31 11:29 UTC (permalink / raw)


"Matthew Heaney" <matthewjheaney@earthlink.net> wrote in
news:1V1Wa.299$jp.55@newsread4.news.pas.earthlink.net: 

> 
> "Ching Bon Lam" <c.lam_REMOVE_THIS@student.utwente.nl> wrote in
> message news:Xns93C9C9EB630Fcblamstudentutwenten@194.109.133.20...
>>
>> that would be:
>>
>> type DB is interfaces.c.extensions.opaque_structure_def;
> 
> This is probably overkill.  For an opaque type all you need to do is:
> 
> type DB_Type is limited null record;
> type DB_Access is access all DB_Type;
> for DB_Access'Storage_Size use 0;
> pragma Convention (C, DB_Access);

overkill? i don't think so.. opaque_structure_def is defined in 
Interfaces.C.Extensions (i-cexten.ads in gnat) as:

subtype opaque_structure_def is System.Address;

just a memory address. That's the same as DB *. Since the api (well, most 
api written in C) only use DB * and not DB, you don't need another access 
type. that's why 

subtype DB is interfaces.c.extensions.opaque_structure_def;

Note that it's actually subtype of opaque_structure_def. small error on my 
side.

> 
> 
>> -- i have too less information about DBTYPE, so i assume
>> -- it's just a struct
>> type DBTYPE is interfaces.c.extensions.opaque_structure_def;
>>
>> function dbopen
>>    (file     : interfaces.c.char_array;
>>     flags    : interfaces.c.int;
>>     mode     : interfaces.c.int;
>>     type     : DBTYPE;
>>     openinfo : interfaces.c.extensions.void_ptr)
>>    return DB;
>>
>> pragma Import(C, dbopen, "dbopen');
> 
> The type of parameter file is incorrect.  The char_array type is an
> unconstrained Ada array type, which does not correspond directly to
> any C type.  Specifically, your problem is that on the Ada side a dope
> vector describing the array object is passed -- this is definitely
> *not* what you want.
> 
> You need to use the type Interfaces.C.Strings.chars_ptr instead.

const char * is in this context the same as a string, which is in fact an 
array of char. and interfaces.c.char_array is the same thing. and with 
chars_ptr you need to make an extra temp variable for the conversion.

> 
> You can probably use System.Address for void*. The C type void* was
> accidently omitted from Interfaces.C in the Ada95 standard, but I
> assume that oversite will be corrected in a future version of the
> language. 

again defined in interfaces.c.extensions (at least in gnat):

subtype void_ptr is System.Address;

> 
> It's not clear whether your return type should be DB or an explicit
> access type (as in DB_Access), because I'm not familiar with the
> package Interfaces.C.extensions.  I would use DB_Access, which is
> completely portable.

i have used interfaces.c.extensions with success, that's why i'm using 
opaque_structure_def because then i don't have to use 'hacks'.

> 
> The type DBTYPE is a bit of a mystery at this point, since structs
> aren't typically passed by value in C.  Perhaps DBTYPE is really a
> pointer? 
> 

i guess :)

CBL




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

* Re: Importing C structs?
  2003-07-31 11:29     ` Ching Bon Lam
@ 2003-07-31 16:59       ` Matthew Heaney
  2003-07-31 17:32         ` Warren W. Gay VE3WWG
  2003-07-31 17:13       ` Matthew Heaney
  2003-07-31 17:40       ` Randy Brukardt
  2 siblings, 1 reply; 28+ messages in thread
From: Matthew Heaney @ 2003-07-31 16:59 UTC (permalink / raw)


Ching Bon Lam <c.lam_REMOVE_THIS@student.utwente.nl> wrote in message news:<Xns93C98A38494B8cblamstudentutwenten@194.109.133.20>...
> "Matthew Heaney" <matthewjheaney@earthlink.net> wrote in
> news:1V1Wa.299$jp.55@newsread4.news.pas.earthlink.net: 
> 
> > This is probably overkill.  For an opaque type all you need to do is:
> > 
> > type DB_Type is limited null record;
> > type DB_Access is access all DB_Type;
> > for DB_Access'Storage_Size use 0;
> > pragma Convention (C, DB_Access);
> 
> overkill? i don't think so.. opaque_structure_def is defined in 
> Interfaces.C.Extensions (i-cexten.ads in gnat) as:
> 
> subtype opaque_structure_def is System.Address;
> 
> just a memory address. That's the same as DB *. Since the api (well, most 
> api written in C) only use DB * and not DB, you don't need another access 
> type. that's why 

A memory address is not the same thing as DB*.  A "memory address" has
type void*.  A void* can point to anything.  A DB* can not.

You are free of course to use System.Address everywhere in Ada, just
as you are free to use void* everywhere in C, but you lose strong
typing that way.  There is a reason why the C API used type DB* and
not type void*.

So I stand by my assertion that type opaque_structure_def is not the
correct choice for a binding to dbopen().



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

* Re: Importing C structs?
  2003-07-31 11:29     ` Ching Bon Lam
  2003-07-31 16:59       ` Matthew Heaney
@ 2003-07-31 17:13       ` Matthew Heaney
  2003-07-31 17:40       ` Randy Brukardt
  2 siblings, 0 replies; 28+ messages in thread
From: Matthew Heaney @ 2003-07-31 17:13 UTC (permalink / raw)


Ching Bon Lam <c.lam_REMOVE_THIS@student.utwente.nl> wrote in message news:<Xns93C98A38494B8cblamstudentutwenten@194.109.133.20>...
> "Matthew Heaney" <matthewjheaney@earthlink.net> wrote in
> news:1V1Wa.299$jp.55@newsread4.news.pas.earthlink.net: 
> 
> > The type of parameter file is incorrect.  The char_array type is an
> > unconstrained Ada array type, which does not correspond directly to
> > any C type.  Specifically, your problem is that on the Ada side a dope
> > vector describing the array object is passed -- this is definitely
> > *not* what you want.
> > 
> > You need to use the type Interfaces.C.Strings.chars_ptr instead.
> 
> const char * is in this context the same as a string, which is in fact an 
> array of char. and interfaces.c.char_array is the same thing. and with 
> chars_ptr you need to make an extra temp variable for the conversion.

It depends on how an object whose type is an unconstrained array is
passed to an operation that has C convention.  The Ada convention is
to pass a dope vector which describes the string (its index bounds and
length).

I just read RM95 B.3 (70), which states that the array really is
passed as a T*, so it looks like you may be OK.  However, note that
B.3 (73) states that it is the programmer's responsibility to ensure
that the array is null terminated, so make sure you don't forget...



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

* Re: Importing C structs?
  2003-07-30 20:52 ` chris
  2003-07-30 21:26   ` Freejack
  2003-07-30 23:50   ` tmoran
@ 2003-07-31 17:14   ` Warren W. Gay VE3WWG
  2003-08-12  0:02     ` chris
  2003-07-31 18:17   ` Xenos
  3 siblings, 1 reply; 28+ messages in thread
From: Warren W. Gay VE3WWG @ 2003-07-31 17:14 UTC (permalink / raw)


chris wrote:

> Freejack wrote:
> 
>> I'm finally starting to get an idea(at least I think I am.) on handling
>> interfacing to C.
> 
> Really?  I don't think I'll ever get the hang of it.

Depending upon the mandates that you're working with
for your project(s), I'll offer this general advice
when interfacing to C facilities:

For complex interactions, like those that involve C
structures, it is sometimes much quicker and reliable
(in the portability sense) to build a layer of C
between the two environments (C wrapper routines).

This helps in several ways:

  - C macros are easily tested and handled
  - sizeof(type) differences are more easily
    addressed (or identified when out of bounds)
  - difficult C structures can be mapped to Ada
    arguments that are more easily handled.
  - C preprocessor work can make the wrapper
    more platform agnostic without affecting
    Ada code changes.
  - Permits more flexibility on the Ada side,
    WRT to records (tagged or controlled etc.)

If OTOH, you must have "as much Ada as possible", or the
ultimate in efficiency, then you'll have more work cut
out for you, at least in the more difficult C/C++ cases.

WRT to C structures and portability, what you may find
is that all your effort will be trashed on another
platform where they have defined some members slightly
differently (different sizes, pad members, different
alignment rules and filling/packing, different order
etc.)  So, if this is a concern, a wrapper is much
safer in the portability sense.

...
> This is from my ongoing work on a libjpeg binding...
> 
>    type Jpeg_Error_Mgr is record
>       Error_Exit          : Error_Exit_Handler;
>       Emit_Message        : Emit_Message_Handler;
>       Output_Message      : Output_Message_Handler;
>       Format_Message      : Format_Message_Handler;
>       Reset_Error_Mgr     : Reset_Error_Handler;
>       Msg_Code            : C.Int;
>       Msg_Parm            : System.Address;
>       Trace_Level         : C.Int;
>       Num_Warnings        : C.Long;
>       Jpeg_Message_Table  : Jpeg_Message_TableT;
>       Last_Jpeg_Message   : C.Int;
>       Addon_Message_Table : Jpeg_Message_TableT;
>       First_Addon_Message : C.Int;
>       Last_Addon_Message  : C.Int;
>    end record;
> 
>    pragma Convention (C, Jpeg_Error_Mgr);

-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




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

* Re: Importing C structs?
  2003-07-31 16:59       ` Matthew Heaney
@ 2003-07-31 17:32         ` Warren W. Gay VE3WWG
  0 siblings, 0 replies; 28+ messages in thread
From: Warren W. Gay VE3WWG @ 2003-07-31 17:32 UTC (permalink / raw)


Matthew Heaney wrote:
> Ching Bon Lam <c.lam_REMOVE_THIS@student.utwente.nl> wrote in message news:<Xns93C98A38494B8cblamstudentutwenten@194.109.133.20>...
> 
>>"Matthew Heaney" <matthewjheaney@earthlink.net> wrote in
>>news:1V1Wa.299$jp.55@newsread4.news.pas.earthlink.net: 
>>
>>>This is probably overkill.  For an opaque type all you need to do is:
>>>
>>>type DB_Type is limited null record;
>>>type DB_Access is access all DB_Type;
>>>for DB_Access'Storage_Size use 0;
>>>pragma Convention (C, DB_Access);
>>
>>overkill? i don't think so.. opaque_structure_def is defined in 
>>Interfaces.C.Extensions (i-cexten.ads in gnat) as:
>>
>>subtype opaque_structure_def is System.Address;
>>
>>just a memory address. That's the same as DB *. Since the api (well, most 
>>api written in C) only use DB * and not DB, you don't need another access 
>>type. that's why 
> 
> A memory address is not the same thing as DB*.  A "memory address" has
> type void*.  A void* can point to anything.  A DB* can not.
> 
> You are free of course to use System.Address everywhere in Ada, just
> as you are free to use void* everywhere in C, but you lose strong
> typing that way.  There is a reason why the C API used type DB* and
> not type void*.
> 
> So I stand by my assertion that type opaque_structure_def is not the
> correct choice for a binding to dbopen().

 From what I have seen in this thread, this "project"
should be a "binding" so that these types of entities are
not directly used by a client program.

In this way, you can carry DB* arround any way that makes
sense, as long as it is properly preserved internally
(perhaps in an Ada tagged record), and nulled
when it is invalid to reference it.

Sometimes within a binding, an external entity's precise makeup
cannot be [conveniently/portably] known. But if you only need
to reference it, then this is no hardship. You then only have
to properly manage its use.

-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




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

* Re: Importing C structs?
  2003-07-31  7:46     ` Freejack
  2003-07-31  9:27       ` Martin Dowie
@ 2003-07-31 17:34       ` Matthew Heaney
  1 sibling, 0 replies; 28+ messages in thread
From: Matthew Heaney @ 2003-07-31 17:34 UTC (permalink / raw)


Freejack <freejack@nospam.net> wrote in message news:<pan.2003.07.31.07.52.36.94842.845@nospam.net>...
> On Thu, 31 Jul 2003 01:35:57 -0400, Matthew Heaney wrote:
> 
> > The type DBTYPE is a bit of a mystery at this point, since structs
> > aren't typically passed by value in C.  Perhaps DBTYPE is really a
> > pointer?
> 
> The header file declares it thusly....
> 
> /*******************************************************
>  * Access methods.
>  *******************************************************/
> /*
>  * !!!
>  * Changes here must be reflected in java/src/com/sleepycat/db/Db.java.
>  */
> 	typedef enum {
> 	DB_BTREE=1,
> 	DB_HASH,
> 	DB_RECNO,
> 	DB_QUEUE,
> 	DB_UNKNOWN			/* Figure it out on open. */
> 	} DBTYPE;
>  
> So I'm assuming I could just use an Ada enumerated type. (It compiles when I
> do this, but it fails at runtime.)

You'll need to use a rep clause to specify that the enumeration
literals start with value 1.  You'll also need to specify convention C
for the enumeration type.

type DBTYPE is (DB_BTREE, DB_HASH, ...);
pragma Convention (C, DBTYPE);
for DBTYPE use (DB_TYPE => 1);  --need others?

Alternatively, you could just use a C int type:

type DBTYPE is new C.int;

DB_BTREE : constant DBTYPE := 1;
DB_HASH : constant DBTYPE := 2;
etc

Sometimes using an integer type to map to a C enum type is the better
choice.


> The second hurdle I'll need to jump is creating a suitable Ada
> replacement for this buttload of defines that occur after the DBTYPE
> declaration.
> 
> /*
>  * DB access method and cursor operation values.  Each value is an operation
>  * code to which additional bit flags are added.
>  */
> #define	DB_AFTER	 1		/* c_put() */
> #define	DB_APPEND	 2		/* put() */
> #define	DB_BEFORE	 3		/* c_put() */

Just use named numbers:

DB_AFTER : constant := 1;
DB_APPEND : constant := 2;
DB_BEFORE : constant := 3;
etc



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

* Re: Importing C structs?
  2003-07-31 11:29     ` Ching Bon Lam
  2003-07-31 16:59       ` Matthew Heaney
  2003-07-31 17:13       ` Matthew Heaney
@ 2003-07-31 17:40       ` Randy Brukardt
  2 siblings, 0 replies; 28+ messages in thread
From: Randy Brukardt @ 2003-07-31 17:40 UTC (permalink / raw)


"Ching Bon Lam" <c.lam_REMOVE_THIS@student.utwente.nl> wrote in message
news:Xns93C98A38494B8cblamstudentutwenten@194.109.133.20...
> overkill? i don't think so.. opaque_structure_def is defined in
> Interfaces.C.Extensions (i-cexten.ads in gnat) as:

That's GNAT-specific stuff; it's not part of Ada. It's best to stick with
standard Ada, especially when doing so is easy (as in this case). Those of
us that use other Ada compilers at least part of the time will be able to
use your software if you do.

One of the nice things about Ada 95 is that interfacing code like this can
easily be written to work with any Ada compiler for the target. That was the
whole idea behind Claw; the fact that only a few lines of Claw's code needs
to be adjusted to particular compilers (mostly for bug workarounds) shows
that Ada 95 code really can be portable.

                    Randy.






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

* Re: Importing C structs?
  2003-07-30 20:52 ` chris
                     ` (2 preceding siblings ...)
  2003-07-31 17:14   ` Warren W. Gay VE3WWG
@ 2003-07-31 18:17   ` Xenos
  2003-07-31 19:16     ` Simon Wright
  3 siblings, 1 reply; 28+ messages in thread
From: Xenos @ 2003-07-31 18:17 UTC (permalink / raw)


We do this sort of think all the time.  Just create an Ada record that is
properly rep. spec'd according to the way your C compiler does its structs.
If the parameter is a pointer to a struct use either System.Address or an
access type.

Unfortunately, there is no portable way to do it.  But you usually don't run
into trouble unless your structs would have misaligned fields.  The compiler
avoids this by creating "holes."  Some C compilers give you limited control
of the packing, but again, its not portable.

Bit fields are nasty because the compiler defined which bit is 0.  For
example, our Ada compiler says that the MSB is 0, where as our C compiler
says that the LSB is, and both are for the same Big Endian machine.

Regards,

Rich

"chris" <spamoff.danx@ntlworld.com> wrote in message
news:ddWVa.1313$Kx1.14581@newsfep4-glfd.server.ntli.net...
> Freejack wrote:
> > I'm finally starting to get an idea(at least I think I am.) on handling
> > interfacing to C.
>
> Really?  I don't think I'll ever get the hang of it.
>
> > Specifically, would I cast DBTYPE as a seperate record type, and then
> > provide a seperate function to translate each item into the type
expected
> > by the C struct? Or can import the DBTYPE struct whole hog into my Ada
> > specification?
>
> Make an Ada record corresponding to that type.  Map it's fields to
> things from interfaces.c and other records.  Then use
>
> pragma Convention(C, DBType);
>
> I think!
>
> This is from my ongoing work on a libjpeg binding...
>
>     type Jpeg_Error_Mgr is record
>        Error_Exit          : Error_Exit_Handler;
>        Emit_Message        : Emit_Message_Handler;
>        Output_Message      : Output_Message_Handler;
>        Format_Message      : Format_Message_Handler;
>        Reset_Error_Mgr     : Reset_Error_Handler;
>        Msg_Code            : C.Int;
>        Msg_Parm            : System.Address;
>        Trace_Level         : C.Int;
>        Num_Warnings        : C.Long;
>        Jpeg_Message_Table  : Jpeg_Message_TableT;
>        Last_Jpeg_Message   : C.Int;
>        Addon_Message_Table : Jpeg_Message_TableT;
>        First_Addon_Message : C.Int;
>        Last_Addon_Message  : C.Int;
>     end record;
>
>     pragma Convention (C, Jpeg_Error_Mgr);
>
>
> HTH,
> Chris
>





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

* Re: Importing C structs?
  2003-07-31 18:17   ` Xenos
@ 2003-07-31 19:16     ` Simon Wright
  2003-07-31 20:17       ` Samuel Tardieu
  2003-07-31 20:40       ` Xenos
  0 siblings, 2 replies; 28+ messages in thread
From: Simon Wright @ 2003-07-31 19:16 UTC (permalink / raw)


"Xenos" <dont.spam.me@spamhate.com> writes:

> We do this sort of think all the time.  Just create an Ada record
> that is properly rep. spec'd according to the way your C compiler
> does its structs.  If the parameter is a pointer to a struct use
> either System.Address or an access type.

I'm pretty sure GNAT will do the Right Thing here (ie pass the address
of the record parameter). I suppose there might be problems with very
small arrays on architectures where these are passed in registers? but
since the Ada and C compilers have the same backend you are quite
likely to be lucky. pragma Convention (C, ) means "do what the C
compiler expects", after all.

The trouble with rep clauses where the C side has none, or hasn't used
them, is that you only need to move to a different architecture
(PowerPC vs i86) for it all to go out of the window.

If you are sending the packets over a network, of course, it's more
difficult.

> Unfortunately, there is no portable way to do it.  But you usually
> don't run into trouble unless your structs would have misaligned
> fields.  The compiler avoids this by creating "holes."  Some C
> compilers give you limited control of the packing, but again, its
> not portable.

With GNAT there's -gnatR which tells you what the representation
actually is.



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

* Re: Importing C structs?
  2003-07-31 19:16     ` Simon Wright
@ 2003-07-31 20:17       ` Samuel Tardieu
  2003-07-31 20:40       ` Xenos
  1 sibling, 0 replies; 28+ messages in thread
From: Samuel Tardieu @ 2003-07-31 20:17 UTC (permalink / raw)


>>>>> "Simon" == Simon Wright <simon@pushface.org> writes:

Simon> I'm pretty sure GNAT will do the Right Thing here (ie pass the
Simon> address of the record parameter). I suppose there might be
Simon> problems with very small arrays on architectures where these
Simon> are passed in registers? but since the Ada and C compilers have
Simon> the same backend you are quite likely to be lucky. pragma
Simon> Convention (C, ) means "do what the C compiler expects", after
Simon> all.

Not exactly, but quite. The RM suggests that any record be passed by
reference, while on most platforms small records (not greater than a
word) are expected on the stack or in a register.

GNAT follows the RM suggestion but allows you to override this choice
by applying pragma Pass_By_Copy (GNAT specific) to your record type.

  Sam
-- 
Samuel Tardieu -- sam@rfc1149.net -- http://www.rfc1149.net/sam



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

* Re: Importing C structs?
  2003-07-31 19:16     ` Simon Wright
  2003-07-31 20:17       ` Samuel Tardieu
@ 2003-07-31 20:40       ` Xenos
  1 sibling, 0 replies; 28+ messages in thread
From: Xenos @ 2003-07-31 20:40 UTC (permalink / raw)



"Simon Wright" <simon@pushface.org> wrote in message
news:x7vispi4id6.fsf@smaug.pushface.org...
> "Xenos" <dont.spam.me@spamhate.com> writes:
>
> > We do this sort of think all the time.  Just create an Ada record
> > that is properly rep. spec'd according to the way your C compiler
> > does its structs.  If the parameter is a pointer to a struct use
> > either System.Address or an access type.
>
> I'm pretty sure GNAT will do the Right Thing here (ie pass the address
> of the record parameter). I suppose there might be problems with very
> small arrays on architectures where these are passed in registers? but

I believe the Ada standard requires that composite types are always sent by
reference, but I still "worry" about a compiler trying to optimize a call
with small records.

> since the Ada and C compilers have the same backend you are quite
> likely to be lucky. pragma Convention (C, ) means "do what the C
> compiler expects", after all.

Unfortunate we weren't so lucky (though we are now!).  We were stuck with
VADS.  Besides, if you DON'T specifically tell Ada to use an address as the
parameter AND you use Conversion to tell it to "do what C expects,"  what to
you think it will do?  Remember that C always passes by value.  Even though
Ada will always send the record by reference (a pointer), C will always send
it by sending the whole structure, unless you specifically tell it to send a
pointer to the record.  So, I think there is some ambiquity there.  I try
and avoid both luck and ambiquity is my software.

>
> The trouble with rep clauses where the C side has none, or hasn't used
> them, is that you only need to move to a different architecture
> (PowerPC vs i86) for it all to go out of the window.

Right, which it why I said that (1) it wasn't portable, and (2) that Ada is
forced to rep. spec. to the C compilers layout.  Changing platforms doesn't
negate the issue.  You still have to make the two sides agree.  Choosing not
to rep. spec. the data is not going to change to need to adapt the code to
the new arch.  At least with the rep. spec. will help to document what the
data is currently expected to look like.  Besides, I don't know of any
language with a portable feature to handle either Endianness or bit order.

>
> If you are sending the packets over a network, of course, it's more
> difficult.

For going over a network, we ALWAYS rep. spec. so that exact layout if
known.  Also requiring the data to be in network byte order takes care of
endian (at least as to defining which one the data is using).  As to bit
ordering for sub- or partial-byte sizes values, I've never seen a clean why
to handle this.  Even Ada has no standard to define which is bit zero.

>
> > Unfortunately, there is no portable way to do it.  But you usually
> > don't run into trouble unless your structs would have misaligned
> > fields.  The compiler avoids this by creating "holes."  Some C
> > compilers give you limited control of the packing, but again, its
> > not portable.
>
> With GNAT there's -gnatR which tells you what the representation
> actually is.





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

* Re: Importing C structs?
  2003-07-31  9:27       ` Martin Dowie
@ 2003-07-31 21:41         ` Freejack
  2003-08-01  7:39           ` Martin Dowie
  0 siblings, 1 reply; 28+ messages in thread
From: Freejack @ 2003-07-31 21:41 UTC (permalink / raw)


On Thu, 31 Jul 2003 05:27:15 -0400, Martin Dowie wrote:
 
> Get a C->Ada converter! c2ada springs to mind
> http://www.averstar.com/~stt/bindings/c2ada/c2ada.html
 
I got it. Still dicking around with the damn thing trying to get it to
compile with python2.2.

I'd upload some maintenance code, if there was a maintainer for it. As it
stands, it looks like it's kind of in limbo.

Freejack



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

* Re: Importing C structs?
  2003-07-31 21:41         ` Freejack
@ 2003-08-01  7:39           ` Martin Dowie
  0 siblings, 0 replies; 28+ messages in thread
From: Martin Dowie @ 2003-08-01  7:39 UTC (permalink / raw)


"Freejack" <freejack@nospam.net> wrote in message
news:pan.2003.07.31.21.47.30.844226.828@nospam.net...
> I got it. Still dicking around with the damn thing trying to get it to
> compile with python2.2.
>
> I'd upload some maintenance code, if there was a maintainer for it. As it
> stands, it looks like it's kind of in limbo.

http://members.tripod.com/vagul/

Try this - it has pre-built binaries (win32)





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

* Re: Importing C structs?
  2003-07-30 23:50   ` tmoran
  2003-07-31 10:53     ` chris
@ 2003-08-04 14:33     ` Andreas Almroth
  2003-08-04 15:16       ` Samuel Tardieu
  1 sibling, 1 reply; 28+ messages in thread
From: Andreas Almroth @ 2003-08-04 14:33 UTC (permalink / raw)


On Wed, 30 Jul 2003 23:50:26 +0000, tmora wrote:

>>   type Jpeg_Error_Mgr is record
>>      ...
>>      Msg_Parm            : System.Address;
> 
>   This is wrong.  The C has
> 
>>   union {
>>     int i[8];
>>     char s[JMSG_STR_PARM_MAX];
>>   } msg_parm;
>   which means msg_parm is JMSG_STR_PARM_MAX number of bytes, interpretable
> sometimes as a char array and sometimes as an int array followed by
> filler.  msg_parm is never an address.  To match the C, I suggest making

I really never have thought about the padding part, but I now see that
when using unions, the C compiler actually pad out to the largest type.
Quite logical actually...

When mapping unions I usually try to mimic the union in (in GNAT mind you)
as in order to get a clearer representation. I got this from "googling" a
bit a while ago;

type Union_Range is new Positive 1..2;
type Some_Union(X : Union_Range := 1) is record
  case X is
    when 1 =>
      I : Int_8_Array;
    when 2 =>
      S : Char_80_Array;
  end case;
end record;
pragma Unchecked_Union(Some_Union);

type Struct_With_Union is record
  X : Interfaces.C.Int;
  Y : Some_Union;
  Z : Interfaces.C.Double;
end record;
pragma Convention(C,Struct_With_Union);

This has worked quite well so far with GNAT, and no need for manual
conversions in the code.
I'm curious if this works with other Ada compilers?


> msg_parm an interfaces.c.char_array (the larger of the two objects),
> and then doing an unchecked_conversion on those (relatively rare)
> occasions when you need to treat it as an array of int's.  Here's
> a compilable example:
> 
> with interfaces.c;
> with ada.unchecked_conversion;
> procedure testluc is
> 
>   JMSG_STR_PARM_MAX: constant := 80;
>   subtype Msg_Parm_C_Type is Interfaces.C.Char_Array(1 .. JMSG_STR_PARM_MAX);
> 
>   subtype I_Part is Interfaces.C.Size_T range 1 .. 32;
>   subtype Msg_Parm_C_I_Part is Interfaces.C.Char_Array(I_Part);
>   type Msg_Parm_I_Type is array(1 .. 8) of Interfaces.C.Int;
> 
>   function To_I is new Ada.Unchecked_Conversion
>     (Source=>Msg_Parm_C_I_Part,
>      Target=>Msg_Parm_I_Type);
> 
>   function To_C is new Ada.Unchecked_Conversion
>     (Source=>Msg_Parm_I_Type,
>      Target=>Msg_Parm_C_I_Part);
> 
>   type Jpeg_Error_Mgr is record
>     msg_parm: Msg_Parm_C_Type;
>   end record;
> 
>   X : Jpeg_Error_Mgr;
>   X_I : Msg_Parm_I_Type;
>   N : Interfaces.C.Int;
> 
> begin
>   -- fetch ints from X.msg_parm
>   N := To_I(X.msg_parm(I_Part))(1);
>   N := To_I(X.msg_parm(I_Part))(2);
>   -- store ints into X.msg_parm
>   X_I(1) := 1;
>   X_I(8) := 2;
>   X.msg_parm(I_Part):=To_C(X_I);
> end testluc;


Cheers,
Andreas




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

* Re: Importing C structs?
  2003-08-04 14:33     ` Andreas Almroth
@ 2003-08-04 15:16       ` Samuel Tardieu
  2003-08-04 20:07         ` Randy Brukardt
  0 siblings, 1 reply; 28+ messages in thread
From: Samuel Tardieu @ 2003-08-04 15:16 UTC (permalink / raw)


>>>>> "Andreas" == Andreas Almroth <andreasNO@SPAMalmroth.com> writes:

Andreas> I'm curious if this works with other Ada compilers?

Probably not, as Unchecked_Union is a GNAT specific pragma.

  Sam
-- 
Samuel Tardieu -- sam@rfc1149.net -- http://www.rfc1149.net/sam



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

* Re: Importing C structs?
  2003-08-04 15:16       ` Samuel Tardieu
@ 2003-08-04 20:07         ` Randy Brukardt
  0 siblings, 0 replies; 28+ messages in thread
From: Randy Brukardt @ 2003-08-04 20:07 UTC (permalink / raw)


"Samuel Tardieu" <sam@rfc1149.net> wrote in message
news:8765ldjvw0.fsf@inf.enst.fr...
> >>>>> "Andreas" == Andreas Almroth <andreasNO@SPAMalmroth.com> writes:
>
> Andreas> I'm curious if this works with other Ada compilers?
>
> Probably not, as Unchecked_Union is a GNAT specific pragma.

...which (probably) will be in Ada 200Y. See AI-00216 (now approved).

I believe AdaMagic-derived compilers support Unchecked_Union (i.e. Aonix,
Green Hills). Others will follow...

                    Randy.






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

* Re: Importing C structs?
  2003-07-31 17:14   ` Warren W. Gay VE3WWG
@ 2003-08-12  0:02     ` chris
  0 siblings, 0 replies; 28+ messages in thread
From: chris @ 2003-08-12  0:02 UTC (permalink / raw)




> WRT to C structures and portability, what you may find
> is that all your effort will be trashed on another
> platform where they have defined some members slightly
> differently (different sizes, pad members, different
> alignment rules and filling/packing, different order
> etc.)  So, if this is a concern, a wrapper is much
> safer in the portability sense.

Thanks for the advice.

It is in my case.  Some things can be different sizes and have different 
forms depending on the environment and how you compile it.  A wrapper 
looks like the best option.


Chris




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

end of thread, other threads:[~2003-08-12  0:02 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-07-30 20:03 Importing C structs? Freejack
2003-07-30 20:52 ` chris
2003-07-30 21:26   ` Freejack
2003-07-30 23:50   ` tmoran
2003-07-31 10:53     ` chris
2003-08-04 14:33     ` Andreas Almroth
2003-08-04 15:16       ` Samuel Tardieu
2003-08-04 20:07         ` Randy Brukardt
2003-07-31 17:14   ` Warren W. Gay VE3WWG
2003-08-12  0:02     ` chris
2003-07-31 18:17   ` Xenos
2003-07-31 19:16     ` Simon Wright
2003-07-31 20:17       ` Samuel Tardieu
2003-07-31 20:40       ` Xenos
2003-07-30 23:14 ` Ching Bon Lam
2003-07-31  0:07   ` tmoran
2003-07-31  5:35   ` Matthew Heaney
2003-07-31  7:46     ` Freejack
2003-07-31  9:27       ` Martin Dowie
2003-07-31 21:41         ` Freejack
2003-08-01  7:39           ` Martin Dowie
2003-07-31 17:34       ` Matthew Heaney
2003-07-31 11:29     ` Ching Bon Lam
2003-07-31 16:59       ` Matthew Heaney
2003-07-31 17:32         ` Warren W. Gay VE3WWG
2003-07-31 17:13       ` Matthew Heaney
2003-07-31 17:40       ` Randy Brukardt
2003-07-31  5:21 ` Matthew Heaney

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