comp.lang.ada
 help / color / mirror / Atom feed
* Calling GNAT-ADA functions from C...
@ 1996-08-08  0:00 Mike Gardner
  1996-08-09  0:00 ` nasser
  0 siblings, 1 reply; 2+ messages in thread
From: Mike Gardner @ 1996-08-08  0:00 UTC (permalink / raw)



Hello,

I was wondering if it is possible to call ADA functions (GNAT version) from C or
C++ on a WIN95 system.  I would think it is possible using GNU compilers but is
it possible for Borland C++ or MSC?  Any ideas on the syntax of calling the
GNAT/ADA functions?  I don't know if the names get mangled.  Does the use of OOP
make this more difficult (i.e. derived/tagged types).

Thanks in advance!

Mike
mike.gardner@ab.com




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

* Re: Calling GNAT-ADA functions from C...
  1996-08-08  0:00 Calling GNAT-ADA functions from C Mike Gardner
@ 1996-08-09  0:00 ` nasser
  0 siblings, 0 replies; 2+ messages in thread
From: nasser @ 1996-08-09  0:00 UTC (permalink / raw)



In article <4ud52r$8qb@news1.cle.ab.com>, mike.gardner@ab.com says...
>
>Hello,
>
>I was wondering if it is possible to call ADA functions (GNAT version) from C or
>C++ on a WIN95 system.  I would think it is possible using GNU compilers but is
>it possible for Borland C++ or MSC?  Any ideas on the syntax of calling the
>GNAT/ADA functions?  I don't know if the names get mangled.  Does the use of OOP
>make this more difficult (i.e. derived/tagged types).
>

Yes it is possible. This is a post I posted here sometimes ago, It is
not perfect offcourse, A little example I did while learning how to call
ada from C and C++, I hope this helps, (ps. to prevent name mangling
by C++ compiler, you use the extern "C" trick ) :

Below is little larger example of a C++ main calling a number of
Ada subprograms, also using arrays.  the Interfaces.C package  has
usefull stuff for interfacing to C/C++, but it does not have
converter functions to convert C arrays to Ada arrays where the
array compononet is other than char,char_array,wchar_t,wchar_array.

So if you pass an array of int (say) to Ada, and you want Ada to
process the array as starting from 1 not from 0, then you need
to convert/"slide" over the array inside the Ada function before
processing it, else you can just leave it the way it is starting
from zero. A simple function will do that, is there is way to
slide the array over on the fly ? (since the array compononets are
different types, one in standard.integer and one is Interfaces.C.int
I could not do it on the fly, so I wrote a function, probably there
is a more elegent way that this.)

I happend to dislike arrays that start from 0, I think arrays that
start from 1, as in Fortran say , are more natural to use, and also
easier to process.

The following are the steps used to build main, and the source code
example. This example is just for testing/learning how to call
Ada from C++, so please dont scream at me if you think it is not the 
most efficient.

steps:

1. first I compile the C++ main

gcc -c main.cc -I/usr/local/lib/g++-include

2. compile the ada package that contains all the ada functions/procedures
that will be called from C++

gcc -c my_pkg.adb

3. bind my_pkg.ali (the .ali file is generated from step 2) :

gnatbind -n my_pkg.ali 

4. link everything togother (with the C++ libraries also offcourse)

gnatlink -L/usr/local/lib my_pkg.ali main.o -lg++ -lstdc++ -o main


main.cc
------
#include <iostream.h>
#include <stdio.h>

extern "C" { void Increment( int* ); 
             int  Sum( int[] , int );
             int  Sum_Version2( int[] , int );
             void Modify( int[] , int );
             void adainit();
             void adafinal();
           }

main()
{
 int i=0;
 int a[5]= {0,1,2,3,4}; 

 adainit();

 Increment(&i);  // we pass address since it is declared IN OUT in ada

 cout<<" after calling Ada, i="<<i<<endl;

 i = Sum(a,sizeof(a)/sizeof(int)); 
                       
 cout<<" in C++, first sum is "<<i<<endl;

 // Now call ada to modify elements of array
 Modify(a,sizeof(a)/sizeof(int));

 i = Sum(a,sizeof(a)/sizeof(int)); 
 cout<<" In C++, Ada did another sum, and the result is "<<i<<endl;

 i = Sum_Version2(a,sizeof(a)/sizeof(int)); 
 cout<<" In C++, Ada did Sum_Version2, and the result is "<<i<<endl;

 adafinal();

 return 0;

}

my_pkg.ads
---------
with Interfaces.C; 

package My_Pkg is
  package C renames Interfaces.C;

  type Ada_Int_Array_type is array(Integer range <>) of Integer;

  type C_Int_Array_type is array(integer range <>) of C.int;

  procedure Modify(A: in out C_Int_Array_type ; Len: in C.Size_t );

  function Sum(A: in C_Int_Array_type ; Len: in C.Size_t ) return C.int;

  function Sum_version2(A: in C_Int_Array_type ; Len: in C.Size_t ) 
                                                        return C.int;

  procedure Increment(I:in out C.int);

  function To_Ada(A: in C_Int_Array_Type; Len: in C.Size_t) 
                                                   return Ada_Int_Array_type;
end My_Pkg;




my_pkg.adb
==========

with Ada.Text_Io; use Ada.Text_Io;
package body My_Pkg is


--
--
--
function Sum(A: in C_Int_Array_type; Len : in C.Size_t ) return C.Int is
The_Sum: Integer;
Length: Integer := Integer(Len);
begin
   The_Sum := 0;
   Put_Line("array from C++ has length " & integer'Image(Length));
   for I in 0 .. Length-1 loop
       Put_line("array from C++ at index " & integer'Image(I) & " is " &
            C.int'Image(A(I)));
       The_Sum := The_Sum + Integer(A(I));
   end loop;
   return C.Int(The_Sum);
end Sum;
pragma Export(C,Sum,"Sum");



--
--
--
function Sum_version2(A: in C_Int_Array_type; Len : in C.Size_t ) 
                                                           return C.Int is
The_Sum: Integer;
Length: Integer := Integer(Len);
Ada_Int_Array: Ada_Int_Array_Type(1..Integer(Len));
begin
   Ada_Int_Array := To_Ada(A,len);
   The_Sum := 0;
   Put_Line("array from C++ has length " & integer'Image(Length));
   for I in 1 .. Length loop
       The_Sum := The_Sum + Ada_Int_array(I);
   end loop;
   return C.Int(The_Sum);
end Sum_version2;
pragma Export(C,Sum_Version2,"Sum_Version2");

--
--
--
procedure Modify(A: in out C_Int_Array_type; Len: in C.Size_t ) is
Length: Integer := Integer(Len);
use Interfaces.C;
begin
   for I in 1 .. Length loop
       A(I) := A(I) * 2;
   end loop;
end Modify;
pragma Export(C,MOdify,"Modify");

--
--
--
procedure Increment(I:in out C.int) is
use Interfaces.C;
begin
   Put_Line("Number passed in is" & C.int'Image(I));
   I := I+1;
end Increment;
pragma Export(C,Increment,"Increment");


--
--
--
function To_Ada(A: in C_Int_Array_Type;Len: C.Size_t) 
                                            return Ada_Int_Array_Type is
Back : Ada_Int_Array_Type(1..Integer(Len));
begin
 for I in Back'Range loop
     Back(I) := Integer(A(I-1));
 end loop;
 return Back;
end To_Ada;
begin
 null;
end My_Pkg;


Nasser
--
Nasser Abbasi. C/C++/Ada Solaris. Perkin Elmer - Applied BioSystem division. 
email:  nasser@apldbio.com   MSEE, MSCS, MSCE, FM.

"640K ought to be enough for anybody."   -- Bill Gates, 1981

"I think there is a world market for maybe five computers." 
Thomas Watson,  chairman of IBM, 1943

"There is no reason anyone would want a computer in their home." 
Ken Olson, president, chairman and founder of Digital Equipment Corp., 1977




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

end of thread, other threads:[~1996-08-09  0:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1996-08-08  0:00 Calling GNAT-ADA functions from C Mike Gardner
1996-08-09  0:00 ` nasser

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