comp.lang.ada
 help / color / mirror / Atom feed
* Newbie question about interface to C
@ 2000-05-30  0:00 David Gressett
  2000-05-30  0:00 ` Keith Thompson
  2000-05-31  0:00 ` Jeff Carter
  0 siblings, 2 replies; 3+ messages in thread
From: David Gressett @ 2000-05-30  0:00 UTC (permalink / raw)


I need to call C routines which  are prototyped like these examples:

shapelessblob *somefunction(char *s);  /* creates a shaplessblob */

int otherfunction(shapelessblob *b);  /* uses a shaplessblob */

where shaplessblob is a pointer to a structure  that is created by
somefunction. The calling Ada code will never look at the insides of a
shapelessblob; It will only pass it to a C routine.

How do I import such a pointer as an Ada access type?

The  Ada LRM that comes with gnat3.12p is not very helpful. (it is,
after all, a RM, not a tutorial.) The Cohen book has only a single
trivial example of a C interface.






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

* Re: Newbie question about interface to C
  2000-05-30  0:00 Newbie question about interface to C David Gressett
@ 2000-05-30  0:00 ` Keith Thompson
  2000-05-31  0:00 ` Jeff Carter
  1 sibling, 0 replies; 3+ messages in thread
From: Keith Thompson @ 2000-05-30  0:00 UTC (permalink / raw)


David Gressett <gressett@iglobal.net> writes:
> I need to call C routines which  are prototyped like these examples:
> 
> shapelessblob *somefunction(char *s);  /* creates a shaplessblob */
> 
> int otherfunction(shapelessblob *b);  /* uses a shaplessblob */
> 
> where shaplessblob is a pointer to a structure  that is created by
> somefunction. The calling Ada code will never look at the insides of a
> shapelessblob; It will only pass it to a C routine.
> 
> How do I import such a pointer as an Ada access type?
> 
> The  Ada LRM that comes with gnat3.12p is not very helpful. (it is,
> after all, a RM, not a tutorial.) The Cohen book has only a single
> trivial example of a C interface.

I'd probably do something like this:

    with Interfaces.C;
    with Interfaces.C.Strings;
    package Foo is
        type Shapeless_Blob is private;
        type Shapeless_Blob_Pointer is access Shapeless_Blob;

        function Some_Function
            (S: Interfaces.C.Strings.chars_ptr)
            return Shapeless_Blob_Pointer
        pragma Import(C, Some_Function, "somefunction");

        function Other_Function
            (B: Shapeless_Blob_Pointer)
            return Interfaces.C.Int;
        pragma Import(C, Other_Function, "otherfunction");

    private
        type Shapeless_Blob is
            record
                Dummy: Interfaces.C.int; -- C doesn't allow empty structs
            end record;
        pragma Convention(C, Shapeless_Blob);
        pragma Convention(C, Shapeless_Blob_Pointer);
    end Foo;

This takes advantage of the fact that all struct pointers in C are
represented the same way (something that's subtly implied by the C
standard).

You could probably get away with declaring
    type Shapeless_Blob_Pointer is new System.Address;
and omitting the declaration of Shapeless_Blob, but it's potentially
less portable; some C implementations might represent, say, struct
pointers and char pointers differently.

-- 
Keith Thompson (The_Other_Keith) kst@cts.com  <http://www.ghoti.net/~kst>
San Diego Supercomputer Center           <*>  <http://www.sdsc.edu/~kst>
Welcome to the last year of the 20th century.




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

* Re: Newbie question about interface to C
  2000-05-30  0:00 Newbie question about interface to C David Gressett
  2000-05-30  0:00 ` Keith Thompson
@ 2000-05-31  0:00 ` Jeff Carter
  1 sibling, 0 replies; 3+ messages in thread
From: Jeff Carter @ 2000-05-31  0:00 UTC (permalink / raw)


David Gressett wrote:
> 
> I need to call C routines which  are prototyped like these examples:
> 
> shapelessblob *somefunction(char *s);  /* creates a shaplessblob */
> 
> int otherfunction(shapelessblob *b);  /* uses a shaplessblob */
> 
> where shaplessblob is a pointer to a structure  that is created by
> somefunction. The calling Ada code will never look at the insides of a
> shapelessblob; It will only pass it to a C routine.
> 
> How do I import such a pointer as an Ada access type?

This cannot be answered completely without knowing how the functions
deal with their parameters. Do they use the initial value? Do they
modify them? For example, if the char* parameter s to somefunction is
used for input only (Ada mode in), then you could declare the function
as taking an Interfaces.C.char_array; pragma Import will perform the
necessary gymnastics to pass a char* to the C.

As for type shapelessblob*, you could probably get by with
System.Address since you don't care what it points to. To be safe,
though, you should do something like

type C_Struct is record
   I : Interfaces.C.Int;
end record;
pragma Convention (C, C_Struct);

type Shapeless_Blob is access all C_Struct;
pragma Convention (C, Shapeless_Blob);

and use Shapeless_Blob for shapelessblob*.

-- 
Jeff Carter
"Hello! Smelly English K...niggets."
Monty Python & the Holy Grail




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

end of thread, other threads:[~2000-05-31  0:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-05-30  0:00 Newbie question about interface to C David Gressett
2000-05-30  0:00 ` Keith Thompson
2000-05-31  0:00 ` Jeff Carter

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