Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ada to c interfaces and CHARS_PTR

505 views
Skip to first unread message

Al Johnston

unread,
Mar 9, 2000, 3:00:00 AM3/9/00
to
I have been trying (for longer than I care to admit) to use the
following c subroutine from
ada:

--- begin c_sub.c ---
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void sub(const char *in_strg_fml,char **inout_strg_fml)
{
char t_buffer[25];
printf(" in c sub\n");

sprintf((char *)&t_buffer," you said => %s <==\0",in_strg_fml);

*inout_strg_fml = strdup(t_buffer);
printf(" %s\n",*inout_strg_fml);

printf(" out c sub\n");
}
---- end c_sub.c ----

I wish to use the type CHARS_PTR from the ada.c.interface.strings
package.
Using this type to interface with c is the whole point of this
exercise. Below is the
section of ada code that attempts to use the above routine. The program
cores
when the c routine returns. I have not been able to find any examples
using
the CHARS_PTR type to interface with c (RM, Rat, GNAT adainc src).


---- begin a_sub.adb ----
with text_io;
with interfaces.c.strings;
use interfaces.c.strings;

package body a_sub is

procedure a_sub is

procedure c_sub(in_strg_fml : CHARS_PTR;
inout_strg_fml : in out CHARS_PTR);
pragma import(c,c_sub,"sub");

in_strg_act : CHARS_PTR;
inout_strg_act : CHARS_PTR := NULL_PTR;

begin
text_io.put_line(" in a_sub");

in_strg_act := NEW_STRING("I am here");

c_sub(in_strg_act,inout_strg_act);
text_io.put_line("----------");
text_io.put_line(" He said ==>> " & VALUE(inout_strg_act) & " <<
==");
text_io.put_line(" out a_sub");
end a_sub;

end a_sub;
---- end a_sub.adb ----

Some one please explan how this is done (using CHARS_PTR).

thanks.

-al


Preben Randhol

unread,
Mar 9, 2000, 3:00:00 AM3/9/00
to
On Thu, 09 Mar 2000 12:53:25 -0500, Al Johnston <sof...@mindspring.com> wrote:
>when the c routine returns. I have not been able to find any examples
>using
>the CHARS_PTR type to interface with c (RM, Rat, GNAT adainc src).

Check PGAda at http://www.infres.enst.fr/ANC/

--
Preben Randhol -- [ran...@pvv.org] -- [http://www.pvv.org/~randhol/]
"Det eneste trygge stedet i verden er inne i en fortelling."
-- Athol Fugard

Gisle Sælensminde

unread,
Mar 9, 2000, 3:00:00 AM3/9/00
to
In article <38C7E515...@mindspring.com>, Al Johnston wrote:
>I have been trying (for longer than I care to admit) to use the
>following c subroutine from
>ada:

C has not 'in out' parameters, only 'in' parameters. To pass the
pointer to the string you can use system'address. str'address is
equivalent to &str in C. The following Ada code can replace
the Ada code of your last posting:

with text_io;
with interfaces.c.strings;
with System;
use interfaces.c.strings;

package body a_sub is

procedure a_sub is

procedure c_sub(in_strg_fml : CHARS_PTR;
inout_strg_fml : System.address);
pragma import(c,c_sub,"sub");

in_strg_act : CHARS_PTR;
inout_strg_act : CHARS_PTR := Null_Ptr;

begin
text_io.put_line(" in a_sub");

in_strg_act := NEW_STRING("I am here");


c_sub(in_strg_act, Inout_Strg_Act'address);

text_io.put_line("----------");
text_io.put_line("He said ==>> "
& VALUE(inout_strg_act) &
" <<==");
text_io.put_line(" out a_sub");
end a_sub;

end a_sub;

--
Gisle Sælensminde ( gi...@ii.uib.no )

ln -s /dev/null ~/.netscape/cookies

Al Johnston

unread,
Mar 9, 2000, 3:00:00 AM3/9/00
to
> C has not 'in out' parameters, only 'in' parameters. To pass the

???? Although I am still trying to figure this stuff out, it seems to
me that c as as much of an in/out as any other language has. To
effect a "in out" or "out" at the lowest level you are always passing
the address of a thing to write to. C just lets you have that method
only, where other languages "hide" this from you by there abstract
"in out" methods. When It comes down to it a language's means for
implementing a inout/out argument is to pass it by reference. this is
what you do when you say "char **foo" in c. The only exception
I have found to this rule is ada, where a inout/out may actually,
according to the RM/Rat be passed by value and then copied
back. But the RM explicitly says that passing by value is NOT
allowed if the convention "c" applies. Since this routine is
a pragma import(c,...) then the out/inout are done by reference,
and therefore should be adding the second level of indirection that
is being used by ada.... But then again, I could by totally
wrong about this... but it is my current understanding...

IN ANY case, I ask for a way using CHARS_PTR; your
solution uses system.address... I have this stuff working
in various places using system.address. The reason I
ask about CHARS_PTR is that I thought the whole
point of the Anx B stuff was so that you did not have
to use such dangerous things as system.address anymore.

Maybe this is where I am wrong... The Rat seems to
be saying you can do this, but it doesn't give an example,
and gnat doesn't seem to do this in its code either...

still looking for help/guidance

-al


Al Johnston

unread,
Mar 9, 2000, 3:00:00 AM3/9/00
to

Thanks... I did... but it hasn't help much. You (they?) show a
binding for a procedure that uses chars_ptr as a formal parameter,
but the is no c code to show me what should be done on the
"callie" side. Thinking that even I could get that to work I did
the following:

procedure foo( bar : chars_ptr);
pragma import(c,foo,"foo")
and
foo(my_chars_ptr);
on the ada side, where
my_chars_ptr : chars_ptr
which was initialized by the appropriate routine.

on the c side I did
void foo(char *bar)
and had the foo routine copy bar to a local array and then
print it out.

running the routine results in the expected behavior for the
c routine, but as it is returning to the ada caller the program
cores...

Am I an idiot or is something screwy... okay... so I am an
idiot... arrrrrrrg.....somebody give me a hand with this.....

I am running gnat 3.12 on a x86 box running rh linux 6.1

Al Johnston

unread,
Mar 10, 2000, 3:00:00 AM3/10/00
to
Okay..

Not only did I not know how to write ada to c interface code,
I apparently have forgotten to write basic c code as well.

In case anyone else doesn't know how to use CHARS_PTR in
an interface to c, here is what seems to work... I make no
claim that it is correct. Runs on RH6.1/x86/gnat3.12.

with text_io;
with interfaces.c.strings;
use interfaces.c.strings;

package body a_sub is

procedure a_sub is

procedure c_sub(in_strg_fml : CHARS_PTR;
inout_strg_fml : in out CHARS_PTR;
accss_strg_fml : access CHARS_PTR);
pragma import(c,c_sub,"c_sub");

in_strg_act : CHARS_PTR;
inout_strg_act : CHARS_PTR;
accss_strg_act : aliased CHARS_PTR;

begin
text_io.put_line(" in a_sub");

in_strg_act := NEW_STRING("I am here");

c_sub(in_strg_act,
inout_strg_act,
accss_strg_act'access);

text_io.put_line(" He said ==>> " & VALUE(inout_strg_act) & " <<
==");

text_io.put_line(" He said ==>> " & VALUE(accss_strg_act) & " <<


==");
text_io.put_line(" out a_sub");
end a_sub;

end a_sub;


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void c_sub(char *in____strg_fml,
char **inout_strg_fml,
char **accss_strg_fml)
{
char t_buffer[50];

printf(" in c sub\n");

sprintf(t_buffer," you said => %s <==",in____strg_fml);
printf("%s\n",t_buffer);

*inout_strg_fml = strdup(t_buffer);
*accss_strg_fml = strdup(t_buffer);

tmo...@bix.com

unread,
Mar 10, 2000, 3:00:00 AM3/10/00
to
If it dies when it tries to do a subroutine return, perhaps the
calling conventions don't match?

Also, what does strdup do? If
*inout_strg_fml = strdup(t_buffer);
means inout_strg_fml := t_buffer[0]'access, then after return,
when t_buffer no longer exist, inout_strg_fml will point to a
garbage location on the popped part of the stack.

Al Johnston

unread,
Mar 10, 2000, 3:00:00 AM3/10/00
to
> If it dies when it tries to do a subroutine return, perhaps the
> calling conventions don't match?

I think they did... the problem was I screwing up the
"body" of my c program (c codeing goof)

> Also, what does strdup do? If
> *inout_strg_fml = strdup(t_buffer);

strdup(3c) allocates new memory and copies the supplied
string to it. It doesnt go away until a free(3c) is called. And
yes.. I know the program has 2 leaks in it.

thanks for the assistance... but my real problem was that
I didn't pay enough attention to my c code...

-al


Simon Wright

unread,
Mar 11, 2000, 3:00:00 AM3/11/00
to
gi...@spurv.ii.uib.no (Gisle Sælensminde) writes:

> C has not 'in out' parameters, only 'in' parameters. To pass the

> pointer to the string you can use system'address. str'address is
> equivalent to &str in C. The following Ada code can replace
> the Ada code of your last posting:

Gisle,

If you do this, you're missing a lot of typechecking.

Certainly on GNAT the compiler has a deep understanding of "convention
C" (this is covered in Annex B.3 (63) ff). I think the one you want is
(68) -- a GNAT chars_ptr is (eventually) a
System.Storage_Elements.Integer_Address -- but if your compiler
doesn't handle this level of interfacing properly I think you should
send it back for a refund!

--------- strs.adb -----------------------------------------------------
with Interfaces.C.Strings;
procedure Strs is
procedure O_Str (O_Str : out Interfaces.C.Strings.Chars_Ptr);
pragma Import (C, O_Str, "o_str");
procedure I_Str (I_Str : Interfaces.C.Strings.Chars_Ptr);
pragma Import (C, I_Str, "i_str");
Str : Interfaces.C.Strings.Chars_Ptr;
begin
O_Str (Str);
I_Str (Str);
end Strs;
------------------------------------------------------------------------

--------- strs_c.c -----------------------------------------------------
#include <stdio.h>
#include <stdlib.h>

char sig[] = "a message from o_str()";

void o_str(char **s)
{
*s = sig;
}

void i_str(char *s)
{
printf("i_str(%s).\n", s);
}
------------------------------------------------------------------------

gcc -c strs_c.c
gnatmake strs -largs strs_c.o

-Simon

Robert Dewar

unread,
Mar 13, 2000, 3:00:00 AM3/13/00
to
In article <38C81310...@mindspring.com>,

Al Johnston <sof...@mindspring.com> wrote:
> > C has not 'in out' parameters, only 'in' parameters. To pass
the
>
> ???? Although I am still trying to figure this stuff out, it
seems to
> me that c as as much of an in/out as any other language has.


No, this is completely wrong, there is a very important semantic
difference between passing a parameter as IN OUT (which in Ada
is often free to pass by copy or by reference), and passing a
pointer by value. You should definitely read up on this in
standard books on programming languages, the difference is
pretty substantial semantically :-)


Sent via Deja.com http://www.deja.com/
Before you buy.

Al Johnston

unread,
Mar 14, 2000, 3:00:00 AM3/14/00
to
>
> If you do this, you're missing a lot of typechecking.

thanks for the example... I am really surprised at the lack of
examples in this area. the problem I had ended up being
carelessness on my part in my c routines... and not with
my ada code at all.

Al Johnston

unread,
Mar 15, 2000, 3:00:00 AM3/15/00
to
> > > C has not 'in out' parameters, only 'in' parameters. To pass
> the
> >
> > ???? Although I am still trying to figure this stuff out, it
> seems to
> > me that c as as much of an in/out as any other language has.
>
> No, this is completely wrong, there is a very important semantic
> difference between passing a parameter as IN OUT (which in Ada

after spend a day trying to get from a STRING to a chars_ptr using
a chain function calls (without calling an allocator routine) I find
that
I am in no position to defined any of my understandings of anything.
It has been a bad day.

Yes, I guess there is a big deference between c's by value and ada's
mode in/out/inout modes. I am just so used to viewing everything
in c as pass by value... if i need to pass a string in c, what really
gets passed is the "value" of the c's address (char *)... or maybe the
"value" of the address where the subroutine is to write the address
of the string (char **).

The ada code I inherited uses " foo : in system.address" as formal
parameters for all of its calls to c. Because of this, I am not used
to thinking about ada passing/returning an array or record by
value... but instead it (ada) returns the "value" of the address
of the array or structure. This view is incredibly limited, and
I know it. If I learned ada from supporting better code, maybe
I wouldn't have such weird understandings.

I tend to vies everything in terms of c's by value model. I think
I better stop this habit QUICKLY.

If you wish to suggest any books in particular, I will make and effort
to get and read them.. I have spent a lot of time in cohen's book,
in the RM and Rat.

-al


tmo...@bix.com

unread,
Mar 15, 2000, 3:00:00 AM3/15/00
to
>I am really surprised at the lack of examples in this area.
You might want to look at the various Windows bindings for
examples. Each one has its own way of doing things, so looking
at several should give a reasonably wide range of examples.

>The ada code I inherited uses " foo : in system.address" as formal
>parameters for all of its calls to c.

Ada 83? OTOH, if it works, why change it?

Robert Dewar

unread,
Mar 15, 2000, 3:00:00 AM3/15/00
to
In article <38CF17B8...@mindspring.com>,

Al Johnston <sof...@mindspring.com> wrote:
> >
> > If you do this, you're missing a lot of typechecking.
>
> thanks for the example... I am really surprised at the lack of
> examples in this area.

That presumably is a comment about the text book you are using
(which I don't think you identified). I hope you are not
talking about the RM here. The RM is not intended as a text
book to learn from! It is a reference source for those who
already know Ada pretty well. About the only exception is
Annex A which is a reasonably accessible description of the
available standard libraries. Otherwise most people will not
want to learn from the RM (I am peculiar, I hate examples,
they seem useless, and I prefer to learn languages from the
standard -- I even learned COBOL from the ANSI standard, but
for most people the RM is NOT the way to learn, and most
people like to learn from example.

The reason by the way that I dislike examples is that at best
they are incomplete and do not define the rules exactly, and
at worst they are wrong (note that the examples in the RM are
not part of the normative text, so have no influence at all
on the definition of the language). But the fact remains that
most people like to learn by example, and that is why all
auxiliary material like manuals and text books should be full
of examples, including ones of the kind asked for in this post.

Al Johnston

unread,
Mar 15, 2000, 3:00:00 AM3/15/00
to
> >parameters for all of its calls to c.
> Ada 83? OTOH, if it works, why change it?

job security :).....

0 new messages