comp.lang.ada
 help / color / mirror / Atom feed
* Question about interfacing C and Ada95
@ 1999-11-08  0:00 Hovers
  1999-11-08  0:00 ` Matthew Heaney
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Hovers @ 1999-11-08  0:00 UTC (permalink / raw)


if I have a c routine that returns more than one value what is thge best way
to interface to Ada with it.


e.g. int getX ( void **instance, int *float );


we have recoded the c to this as Ada funcs do not allow more than one return
val;

void getX ( void **instance, int *float, int *error );



How do I then write the Ada to interface to this in Ada 95.



Cheers


Paul Hussein.









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

* Re: Question about interfacing C and Ada95
  1999-11-08  0:00 Question about interfacing C and Ada95 Hovers
@ 1999-11-08  0:00 ` Matthew Heaney
  1999-11-08  0:00 ` Robert Dewar
  1999-11-08  0:00 ` tmoran
  2 siblings, 0 replies; 12+ messages in thread
From: Matthew Heaney @ 1999-11-08  0:00 UTC (permalink / raw)


In article <806ud0$lu1$1@trog.dera.gov.uk> , "Hovers" 
<hovers@dera.gov.uk> wrote:

> if I have a c routine that returns more than one value what is thge best way
> to interface to Ada with it.
>
>
> e.g. int getX ( void **instance, int *float );

Just use access paramaters to pass data as an out parameter.

What kind of data is "instance"?  It looks like you have out param that
returns an array-of-void (or is it an array of pointer-to-void?).  Can
you be more specific about the type?

And why on earth did you name an out param (of type int) "float"?



> we have recoded the c to this as Ada funcs do not allow more than one return
> val;
>
> void getX ( void **instance, int *float, int *error );

This is incorrect.  Ada is *identical* to C wrt the fact that a function
has only one return value.  (A "return value" is not the same as an "out
parameter.")  So there was no reason to rewrite your C declaration as a
function that returns void; the original version was just fine.

--
The new standards [for science curricula in Kansas] do not forbid the
teaching of evolution, but the subject will no longer be included in
statewide tests for evaluating students--a virtual guarantee, given the
realities of education, that this central concept of biology will be
diluted or eliminated, thus reducing courses to something like chemistry
without the periodic table, or American history without Lincoln.

Stephen Jay Gould, Time, 23 Aug 1999




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

* Re: Question about interfacing C and Ada95
  1999-11-08  0:00 Question about interfacing C and Ada95 Hovers
  1999-11-08  0:00 ` Matthew Heaney
@ 1999-11-08  0:00 ` Robert Dewar
  1999-11-09  0:00   ` Hovers
  1999-11-08  0:00 ` tmoran
  2 siblings, 1 reply; 12+ messages in thread
From: Robert Dewar @ 1999-11-08  0:00 UTC (permalink / raw)


In article <806ud0$lu1$1@trog.dera.gov.uk>,
  "Hovers" <hovers@dera.gov.uk> wrote:
> if I have a c routine that returns more than one value what is
thge best way
> to interface to Ada with it.
>
> e.g. int getX ( void **instance, int *float );
>
> we have recoded the c to this as Ada funcs do not allow more
> than one return

Both Ada and C allow exactly one value to be returned.

Both Ada and C allow pointers to be passed by value, allowing
the called subprogram (function or procedure in Ada) to modify
the calling parameter.

Ada in addition for procedures only, has a feature (out
parameters) that is not allowed in C at all.

But it does not seem there is any significant problem here!

Yes, it would be nice if you could model pointer parameters in
C with out parameters in functions in Ada, but you can't and
you certainly don't need to. Just call the function as you
would in C, passing a pointer if the parameter is of a pointer
type.

If necessary (but please ONLY if necessary) use aliased and
'Access to pass a pointer to a declared variable.





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




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

* Re: Question about interfacing C and Ada95
  1999-11-08  0:00 Question about interfacing C and Ada95 Hovers
  1999-11-08  0:00 ` Matthew Heaney
  1999-11-08  0:00 ` Robert Dewar
@ 1999-11-08  0:00 ` tmoran
  1999-11-09  0:00   ` Robert Dewar
  2 siblings, 1 reply; 12+ messages in thread
From: tmoran @ 1999-11-08  0:00 UTC (permalink / raw)


>we have recoded the c to this as Ada funcs do not allow more than
>one return val;
>
>void getX ( void **instance, int *float, int *error );
>
>How do I then write the Ada to interface to this in Ada 95.
  procedure getX(M     : in out Matrix;
                 Float : in out integer;
                 Error : out integer);
or so, depending on just what you want.
  Actually, both Ada and C allow a single return value from a
function, ie "result = getX(....);", but Ada in addition allows
"out" or "in out" parameters to procedures, which in C must be
simulated by passing "in" a pointer to the target parameter.




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

* Re: Question about interfacing C and Ada95
  1999-11-08  0:00 ` tmoran
@ 1999-11-09  0:00   ` Robert Dewar
  0 siblings, 0 replies; 12+ messages in thread
From: Robert Dewar @ 1999-11-09  0:00 UTC (permalink / raw)


In article <zDFV3.101$Wi2.9657@typhoon-sf.snfc21.pbi.net>,
  tmoran@bix.com wrote:
> >we have recoded the c to this as Ada funcs do not allow more
than
> >one return val;
> >
> >void getX ( void **instance, int *float, int *error );
> >
> >How do I then write the Ada to interface to this in Ada 95.
>   procedure getX(M     : in out Matrix;
>                  Float : in out integer;
>                  Error : out integer);
> or so, depending on just what you want.
>   Actually, both Ada and C allow a single return value from a
> function, ie "result = getX(....);", but Ada in addition
allows
> "out" or "in out" parameters to procedures, which in C must be
> simulated by passing "in" a pointer to the target parameter.


Note incidentally, that, following the DEC ADa 83 design, GNAT
provides value returning procedures that allow modeling of
external functions with out parameters. See description of
Import_Valued_Procedure pragma in DEC or GNAT documentation.


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




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

* Re: Question about interfacing C and Ada95
  1999-11-08  0:00 ` Robert Dewar
@ 1999-11-09  0:00   ` Hovers
  1999-11-09  0:00     ` Ted Dennison
  1999-11-09  0:00     ` Matthew Heaney
  0 siblings, 2 replies; 12+ messages in thread
From: Hovers @ 1999-11-09  0:00 UTC (permalink / raw)


In followup would this be sort of correct.

It falls over however on the first text_io.put_line

Thanks for your help.
================================ C CODE ======================
/* standard includes */

#include <stdlib.h>

#include <stdio.h>

typedef struct

{

float val;

} INSTANCE;

void createObject ( void **inst, int *error_code )

{

*inst = malloc ( sizeof ( INSTANCE ) );

( ( INSTANCE * ) *inst )->val = 10.0f;

*error_code = 1;

}

void getFloat ( void **inst, float *val, int *error_code )

{

*val = ( ( INSTANCE * ) *inst )->val;

*error_code = 1;

}

================== ADA CODE =======================
with Text_IO;

with Interfaces.C;

with SYSTEM;

procedure get is

   type Access_Int_Type is access Interfaces.C.Int;

   type Access_C_Float_Type is access Interfaces.C.C_Float;

   type Instance_Type is access SYSTEM.ADDRESS;

   Error_Code : Access_Int_Type := NULL;

   Instance : Instance_Type := NULL;

   Val : Access_C_Float_Type := NULL;

   procedure Create_Object

      ( Instance : in out Instance_Type;

        Error_Code : in out Access_Int_Type );

       pragma Import ( C, Create_Object, "createObject" );

       procedure Get_Float

       ( Instance : in out Instance_Type;

        Val : in out Access_C_Float_Type;

        Error_Code : in out Access_Int_Type );

         pragma Import ( C, Get_Float, "getFloat" );

begin -- get

   Create_Object ( Instance, Error_Code );

   Text_IO.Put_Line ( Interfaces.C.Int'image ( Error_Code.all ) );

   Get_Float ( Instance, Val, Error_Code );

   Text_IO.Put_Line ( Interfaces.C.Int'image ( Error_Code.all ) );


end get;

"Robert Dewar" <robert_dewar@my-deja.com> wrote in message
news:8076h5$d3c$1@nnrp1.deja.com...
> In article <806ud0$lu1$1@trog.dera.gov.uk>,
>   "Hovers" <hovers@dera.gov.uk> wrote:
> > if I have a c routine that returns more than one value what is
> thge best way
> > to interface to Ada with it.
> >
> > e.g. int getX ( void **instance, int *float );
> >
> > we have recoded the c to this as Ada funcs do not allow more
> > than one return
>
> Both Ada and C allow exactly one value to be returned.
>
> Both Ada and C allow pointers to be passed by value, allowing
> the called subprogram (function or procedure in Ada) to modify
> the calling parameter.
>
> Ada in addition for procedures only, has a feature (out
> parameters) that is not allowed in C at all.
>
> But it does not seem there is any significant problem here!
>
> Yes, it would be nice if you could model pointer parameters in
> C with out parameters in functions in Ada, but you can't and
> you certainly don't need to. Just call the function as you
> would in C, passing a pointer if the parameter is of a pointer
> type.
>
> If necessary (but please ONLY if necessary) use aliased and
> 'Access to pass a pointer to a declared variable.
>
>
>
>
>
> Sent via Deja.com http://www.deja.com/
> Before you buy.






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

* Re: Question about interfacing C and Ada95
  1999-11-09  0:00   ` Hovers
@ 1999-11-09  0:00     ` Ted Dennison
  1999-11-12  0:00       ` Hovers
  1999-11-09  0:00     ` Matthew Heaney
  1 sibling, 1 reply; 12+ messages in thread
From: Ted Dennison @ 1999-11-09  0:00 UTC (permalink / raw)


In article <808la7$4b9$1@trog.dera.gov.uk>,
  "Hovers" <hovers@dera.gov.uk> wrote:
> In followup would this be sort of correct.
>
> It falls over however on the first text_io.put_line

If your compiler follows the implementation advice, that's exactly what
I'd expect to happen. See below.

> void createObject ( void **inst, int *error_code )

So the C side thinks its getting a pointer to an integer for error_code.

>    type Access_Int_Type is access Interfaces.C.Int;
>    Error_Code : Access_Int_Type := NULL;
>    procedure Create_Object
>       ( Instance : in out Instance_Type;
>         Error_Code : in out Access_Int_Type );
>        pragma Import ( C, Create_Object, "createObject" );

If your compiler follows the implmentation advice in the RM, "in out
Access_Int_Type" will be roughly equivalent to a C "*Access_Int_Type".
In other words, what C will be getting is a *pointer* to the Error_Code
object you pass in on the Ada side (which is itself a pointer). So in
effect C is looking for a *int, but you will be giving it a **int.

>    Create_Object ( Instance, Error_Code );

So here you pass in Error_Code, which Ada passes to C as a pointer to
Error_Code (which itself is a null pointer), C dereferences your
pointer, and overrides the NULL there with an error return code (let's
assume the value is 1).

>    Text_IO.Put_Line ( Interfaces.C.Int'image ( Error_Code.all ) );

Error_Code's value is now 1. That most likely is not a valid address for
a pointer in your system. Now you try to dereference it and print the
value of the integer at memory location 1. *BOOM*!

--
T.E.D.


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




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

* Re: Question about interfacing C and Ada95
  1999-11-09  0:00   ` Hovers
  1999-11-09  0:00     ` Ted Dennison
@ 1999-11-09  0:00     ` Matthew Heaney
  1 sibling, 0 replies; 12+ messages in thread
From: Matthew Heaney @ 1999-11-09  0:00 UTC (permalink / raw)


The following Ada code works correctly with the C code you posted in 
your last message.

If you prefer to use functions (instead of procedures), in order to
return the Error_Code as the return value of the function, it's simple
enough to do that.


--STX
with Text_IO;       use Text_IO;
with Interfaces.C;  use Interfaces;
with System;

procedure get is

   type Access_Int_Type is access all C.Int;
   pragma Convention (C, Access_Int_Type);

   type Access_C_Float_Type is access all C.C_Float;
   pragma Convention (C, Access_C_Float_Type);

   type Instance_Type is access all System.Address;
   pragma Convention (C, Instance_Type);

   Error_Code : aliased C.Int;

   Instance : aliased System.Address;

   Val : aliased C.C_Float;

   procedure Create_Object
     (Instance   : in Instance_Type;
      Error_Code : in Access_Int_Type);

   pragma Import (C, Create_Object, "createObject");

   procedure Get_Float
     (Instance   : in Instance_Type;
      Val        : in Access_C_Float_Type;
      Error_Code : in Access_Int_Type);

   pragma Import (C, Get_Float, "getFloat");

begin -- get

   Create_Object (Instance'Access, Error_Code'Access);

   Put_Line (C.Int'Image (Error_Code));

   Get_Float (Instance'Access, Val'Access, Error_Code'Access);

   Put_Line (C.Int'Image (Error_Code));
   Put_Line (C.C_Float'Image (Val));

end get;




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

* Re: Question about interfacing C and Ada95
  1999-11-12  0:00         ` Robert Dewar
@ 1999-11-12  0:00           ` Ted Dennison
  1999-11-13  0:00             ` Robert Dewar
  0 siblings, 1 reply; 12+ messages in thread
From: Ted Dennison @ 1999-11-12  0:00 UTC (permalink / raw)


In article <80h2uc$kbt$1@nnrp1.deja.com>,
  Robert Dewar <robert_dewar@my-deja.com> wrote:
> In article <80gh96$82d$1@trog.dera.gov.uk>,
>   "Hovers" <hovers@dera.gov.uk> wrote:
> > So essentially in out = *param

More or less, yes. The same goes for "out".

>
> Read the exact rules in the RM, and make sure that your compiler
> documents that it follows them (this documentation must be
> present in a conforming compiler, it is required, see annex M)

True. And (just to tweak Robert a bit :-) ) I'll also point out that it
is meerly "implementation advice" that it work this way. But this is
something you should be able to count on, and yell at your vendor if it
doesn't work.

--
T.E.D.


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




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

* Re: Question about interfacing C and Ada95
  1999-11-09  0:00     ` Ted Dennison
@ 1999-11-12  0:00       ` Hovers
  1999-11-12  0:00         ` Robert Dewar
  0 siblings, 1 reply; 12+ messages in thread
From: Hovers @ 1999-11-12  0:00 UTC (permalink / raw)


Cheers Ted.

So used to VADS 83 compiler that in out params never worked, so I was
getting confused.

So essentially in out = *param

Cheers








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

* Re: Question about interfacing C and Ada95
  1999-11-12  0:00       ` Hovers
@ 1999-11-12  0:00         ` Robert Dewar
  1999-11-12  0:00           ` Ted Dennison
  0 siblings, 1 reply; 12+ messages in thread
From: Robert Dewar @ 1999-11-12  0:00 UTC (permalink / raw)


In article <80gh96$82d$1@trog.dera.gov.uk>,
  "Hovers" <hovers@dera.gov.uk> wrote:
> So essentially in out = *param

Read the exact rules in the RM, and make sure that your compiler
documents that it follows them (this documentation must be
present in a conforming compiler, it is required, see annex M)


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




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

* Re: Question about interfacing C and Ada95
  1999-11-12  0:00           ` Ted Dennison
@ 1999-11-13  0:00             ` Robert Dewar
  0 siblings, 0 replies; 12+ messages in thread
From: Robert Dewar @ 1999-11-13  0:00 UTC (permalink / raw)


In article <80hge1$upk$1@nnrp1.deja.com>,
  Ted Dennison <dennison@telepath.com> wrote:

> > Read the exact rules in the RM, and make sure that your
> > compiler documents that it follows them (this documentation
> > must be present in a conforming compiler, it is required,
> > see annex M)

> True. And (just to tweak Robert a bit :-) ) I'll also point
> out that it is meerly "implementation advice" that it work
> this way. But this is something you should be able to count
> on, and yell at your vendor if it
> doesn't work.

This really rates a huh? Ted, the *reason* that I said above
that you should check that your compiler follows these is
*precisely* that they are IA. Of course you do not have to
check documentation to see whether your compiler follows
required normative rules!

THe point is that in evaluating compilers, you must be able to
easily check if some given IA is followed, since compilers are
required by Annex M to provide this information in their
documentation (the relevant documentation in GNAT's case can
be found in the GNAT programmers reference manual for example,
but there must be equivalent documentation in any compiler
claiming conformance to the Ada 95 RM.

As Bob has pointed out, Ada 95 tends to go much further in
specifying such things than other languages. They are IA simply
because it is (quite obviously) impossible to formalize these
kind of interface rules.


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




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

end of thread, other threads:[~1999-11-13  0:00 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-11-08  0:00 Question about interfacing C and Ada95 Hovers
1999-11-08  0:00 ` Matthew Heaney
1999-11-08  0:00 ` Robert Dewar
1999-11-09  0:00   ` Hovers
1999-11-09  0:00     ` Ted Dennison
1999-11-12  0:00       ` Hovers
1999-11-12  0:00         ` Robert Dewar
1999-11-12  0:00           ` Ted Dennison
1999-11-13  0:00             ` Robert Dewar
1999-11-09  0:00     ` Matthew Heaney
1999-11-08  0:00 ` tmoran
1999-11-09  0:00   ` Robert Dewar

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