comp.lang.ada
 help / color / mirror / Atom feed
* how to pass access string across pragma C interface?
@ 1997-06-19  0:00 burch
  1997-06-20  0:00 ` Anonymous
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: burch @ 1997-06-19  0:00 UTC (permalink / raw)



I'm using Ada83 with the Alsys compiler and I'm having problems getting
access strings to pass to C char* across the pragma interface call.  What
kind of type definitions does one have to do on the Ada side to get the
types to match up?  This is what I've done so far, which gives a
constraint error on run time.
	type string_access_type is access string( 1 ..2048);

	function read_func (
             socket_fd : in integer;
             buffer : in string_access_type
             ) return integer;
        pragma interface ( C , read_func );
        pragma interface_name( read_func, "read" );

			.
			.
			.
       begin


  			.
			.
       status_read := read_func ( socket_fd, buffer );

the C function "read" is

int read (int, char*);

What I'm trying to accomplish is to have "buffer" passed by reference to
C.  C will go out and get the string from a socket, return, and
(hopefully) I'll be able to use it back on the Ada side.

I'm new with with Ada, so any comments for my learning would be
appreciated.  Thank you in advance.

Tim Burch
burch@cyberhighway.net

-------------------==== Posted via Deja News ====-----------------------
      http://www.dejanews.com/     Search, Read, Post to Usenet




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

* Re: how to pass access string across pragma C interface?
  1997-06-19  0:00 how to pass access string across pragma C interface? burch
@ 1997-06-20  0:00 ` Anonymous
  1997-06-22  0:00 ` David C. Hoos, Sr.
  1997-06-24  0:00 ` Matthew Heaney
  2 siblings, 0 replies; 6+ messages in thread
From: Anonymous @ 1997-06-20  0:00 UTC (permalink / raw)



On Thu, 19 Jun 1997 10:41:08 -0600, burch@cyberhighway.net wrote:

> I'm using Ada83 with the Alsys compiler and I'm having problems getting
> access strings to pass to C char* across the pragma interface call.  What
> kind of type definitions does one have to do on the Ada side to get the
> types to match up?  This is what I've done so far, which gives a
> constraint error on run time.
> 	type string_access_type is access string( 1 ..2048);
> 
> 	function read_func (
>              socket_fd : in integer;
>              buffer : in string_access_type
>              ) return integer;
>         pragma interface ( C , read_func );
>         pragma interface_name( read_func, "read" );
> 
> 			.
> 			.
> 			.
>        begin
> 
> 
>   			.
> 			.
>        status_read := read_func ( socket_fd, buffer );
> 
> the C function "read" is
> 
> int read (int, char*);
> 
> What I'm trying to accomplish is to have "buffer" passed by reference to
> C.  C will go out and get the string from a socket, return, and
> (hopefully) I'll be able to use it back on the Ada side.
> 
> I'm new with with Ada, so any comments for my learning would be
> appreciated.  Thank you in advance.

In Ada 83, you have to define the function as accepting an address:

Buffer : String (1 .. 2048);
..
function Read (Socket : Integer; Buffer : System.Address) return
Integer;
pragma Interface (C, Read);
..
Result := Read (Socket, Buffer (1)'Address);

In Ada (Ada 95, ISO/IEC 8652:1995), you can use an access parameter:

subtype Buffer_String is String (1 .. 2048);

Buffer : aliased Buffer_String;
..
function Read (Socket : Integer; Buffer : access Buffer_String) return
Integer;
pragma Import (C, Read);
..
Result := Read (Socket, Buffer'access);

Jeff Carter  PGP:1024/440FBE21
My real e-mail address: ( carter @ innocon . com )
"Now go away, or I shall taunt you a second time."
Monty Python & the Holy Grail

Posted with Spam Hater - see
http://www.compulink.co.uk/~net-services/spam/






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

* Re: how to pass access string across pragma C interface?
  1997-06-19  0:00 how to pass access string across pragma C interface? burch
  1997-06-20  0:00 ` Anonymous
@ 1997-06-22  0:00 ` David C. Hoos, Sr.
  1997-06-23  0:00   ` Robert Dewar
  1997-06-24  0:00 ` Matthew Heaney
  2 siblings, 1 reply; 6+ messages in thread
From: David C. Hoos, Sr. @ 1997-06-22  0:00 UTC (permalink / raw)



Hi Tim,

Hour code does not show the declaration of "buffer": used in the call to
"read", so
it is possible that there is a problem associated with that.

Since I am not familiar with your compiler (you didn't specify a platform),
my remarks
have certain underlying assumptions which I will specify.

Assuming that the bit pattern for an access value and a C pointer are
identical on your
platform (this assumption is implicit in your interface pragma), then you
should
do something like:
buffer : string_access_type := new string (1 .. 2048);

My own preference for doing this sort of thing is not to use dynamic
memory, but
instead to specify the Ada System.Address type for parameters corresponding
to C pointers.  Then I use a variable declaration such as Buffer:string (1
. 2048),
and call the procedure with buffer'address for the System.Address
parameter.

This has the advantage of not tying your declaration of "read" to a
specific
buffer size.

Of course, you need to use the ststus_read value to determine how many
bytes
were returned.  If the value returned was --1, then you need to look at the
errno
value to determine what went wrong.  For example, if the errno value is
EINTR,
you would know that the read was interrupted, and that you should increment
the
address value by that many bytes and call read again (another reason for
making
the C pointer equivalent a System.Address value instead of an access
value)..

One final thing puzzles me.  Usually read functions like this have another
integer
parameter -- i.e., the number of bytes to read.

Hope all this helps.

-- 
David C. Hoos, Sr.,
http://www.dbhwww.com
http://www.ada95.com

burch@cyberhighway.net wrote in article <866734587.8496@dejanews.com>...
> I'm using Ada83 with the Alsys compiler and I'm having problems getting
> access strings to pass to C char* across the pragma interface call.  What
> kind of type definitions does one have to do on the Ada side to get the
> types to match up?  This is what I've done so far, which gives a
> constraint error on run time.
> 	type string_access_type is access string( 1 ..2048);
> 
> 	function read_func (
>              socket_fd : in integer;
>              buffer : in string_access_type
>              ) return integer;
>         pragma interface ( C , read_func );
>         pragma interface_name( read_func, "read" );
> 
> 			.
> 			.
> 			.
>        begin
> 
> 
>   			.
> 			.
>        status_read := read_func ( socket_fd, buffer );
> 
> the C function "read" is
> 
> int read (int, char*);
> 
> What I'm trying to accomplish is to have "buffer" passed by reference to
> C.  C will go out and get the string from a socket, return, and
> (hopefully) I'll be able to use it back on the Ada side.
> 
> I'm new with with Ada, so any comments for my learning would be
> appreciated.  Thank you in advance.
> 
> Tim Burch
> burch@cyberhighway.net
> 
> -------------------==== Posted via Deja News ====-----------------------
>       http://www.dejanews.com/     Search, Read, Post to Usenet
> 




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

* Re: how to pass access string across pragma C interface?
  1997-06-22  0:00 ` David C. Hoos, Sr.
@ 1997-06-23  0:00   ` Robert Dewar
  1997-06-25  0:00     ` Alan Brain
  0 siblings, 1 reply; 6+ messages in thread
From: Robert Dewar @ 1997-06-23  0:00 UTC (permalink / raw)



David says

<<Assuming that the bit pattern for an access value and a C pointer are
identical on your
platform (this assumption is implicit in your interface pragma), then you
should
do something like:
buffer : string_access_type := new string (1 .. 2048);
>>


It is reasonable to assume that pointers to constrained array types are
easily mapped to C pointers, but it is asking for trouble to pass
pointers to unconstrained types. That is because the bounds information
must be somehow present, and C cannot know anything about it.

Thus code that passes such pointers to C, and even more code that receives
such pointers FROM C, is liable to be highly implementation dependent.





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

* Re: how to pass access string across pragma C interface?
  1997-06-19  0:00 how to pass access string across pragma C interface? burch
  1997-06-20  0:00 ` Anonymous
  1997-06-22  0:00 ` David C. Hoos, Sr.
@ 1997-06-24  0:00 ` Matthew Heaney
  2 siblings, 0 replies; 6+ messages in thread
From: Matthew Heaney @ 1997-06-24  0:00 UTC (permalink / raw)



In article <866734587.8496@dejanews.com>, burch@cyberhighway.net wrote:

>I'm using Ada83 with the Alsys compiler and I'm having problems getting
>access strings to pass to C char* across the pragma interface call.  What
>kind of type definitions does one have to do on the Ada side to get the
>types to match up?  This is what I've done so far, which gives a
>constraint error on run time.
>        type string_access_type is access string( 1 ..2048);
>
>        function read_func (
>             socket_fd : in integer;
>             buffer : in string_access_type
>             ) return integer;
>        pragma interface ( C , read_func );
>        pragma interface_name( read_func, "read" );
>
>                        .
>                        .
>                        .
>       begin
>
>
>                        .
>                        .
>       status_read := read_func ( socket_fd, buffer );
>
>the C function "read" is
>
>int read (int, char*);
>
>What I'm trying to accomplish is to have "buffer" passed by reference to
>C.  C will go out and get the string from a socket, return, and
>(hopefully) I'll be able to use it back on the Ada side.

You don't need to use Ada access types.  When transferring data across an
external interface, use System.Address on a buffer allocated on the stack:

declare
   function read
     (fd : Interfaces.C.int; 
      Buffer : System.Address) return Interfaces.C.int;

   pragma Interface (C, read);
   pragma Interface_Name (read, "read");

   The_Buffer : String (1 .. 2048);                         
   pragma Volatile (The_Buffer);  -- ???

-- or perhaps we need to make it aliased ???
-- The_Buffer : aliased String (1 .. 2048);
-- pragma Volatile (The_Buffer);

   The_Status : constant Interfaces.C.int :=
      read (fd, The_Buffer (1)'Address);
begin
...

Please don't put the buffer on the heap; this is completely unnecessary.

Perhaps "Robert and the Bobs" can provide info about whether pragma
Volatile or aliased is necessary.

You can make the interface even more bulletproof by using the string
(character array) types declared in package Interfaces.C.  But the code
fragment above should work for you.

Email me if you're having any more problems.

Matt

--------------------------------------------------------------------
Matthew Heaney
Software Development Consultant
<mailto:matthew_heaney@acm.org>
(818) 985-1271




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

* Re: how to pass access string across pragma C interface?
  1997-06-23  0:00   ` Robert Dewar
@ 1997-06-25  0:00     ` Alan Brain
  0 siblings, 0 replies; 6+ messages in thread
From: Alan Brain @ 1997-06-25  0:00 UTC (permalink / raw)



Robert Dewar wrote:

> It is reasonable to assume that pointers to constrained array types are
> easily mapped to C pointers, but it is asking for trouble to pass
> pointers to unconstrained types. That is because the bounds information
> must be somehow present, and C cannot know anything about it.
> 
> Thus code that passes such pointers to C, and even more code that receives
> such pointers FROM C, is liable to be highly implementation dependent.

Correct. What you must do is to have a look at the compiler
documentation. For BOTH C and Ada compilers. For the C Compiler, this
will often mean looking at the source code for it (bleah). All Ada
compilers in my experience state somewhere what the compiler's native
representation of each data structure looks like. It took me 3 days to
find it in the DDCI manuals once, but they have improved markedly since
then.
For example, one implementation may look like:
2 bytes giving a tag for this data structure (uunconstrained array,
short unconstrained array, huge unconstrained array etc)
2-bytes giving an entry into a hash table of memory locations for start
and length OR 2 bytes for length and 4 bytes for start address if it's a
small unconstrained array.
Another implementation may be completely different: just a 4-bytes
length, with the data starting immediately afterwards.

As for C, C++... they vary as well. If you're incredibly fortunate, then
the internal representations might be identical. But in this case, I'd
still write a wrapper, and put this with the other machine-dependent
stuff, as different versions of the compilers can change their
representations without notice.
   
-- 
aebrain@dynamite.com.au     <> <>    How doth the little Crocodile
| Alan & Carmel Brain|      xxxxx       Improve his shining tail?
| Canberra Australia |  xxxxxHxHxxxxxx _MMMMMMMMM_MMMMMMMMM
100026.2014 compuserve o OO*O^^^^O*OO o oo     oo oo     oo  
                    By pulling MAERKLIN Wagons, in 1/220 Scale
See http://www.z-world.com/graphics/z/master/8856.gif for picture






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

end of thread, other threads:[~1997-06-25  0:00 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-06-19  0:00 how to pass access string across pragma C interface? burch
1997-06-20  0:00 ` Anonymous
1997-06-22  0:00 ` David C. Hoos, Sr.
1997-06-23  0:00   ` Robert Dewar
1997-06-25  0:00     ` Alan Brain
1997-06-24  0:00 ` Matthew Heaney

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