From: nasser@apldbio.com (Nasser Abbasi)
Subject: on calling Ada from C/C++
Date: 1996/06/12
Date: 1996-06-12T00:00:00+00:00 [thread overview]
Message-ID: <nhpw75iqsp.fsf@paralysys> (raw)
this is fyi:
This is a little note about calling Ada subprogram from C++ .
I started 2-3 hours ago to learn how to call Ada from C++, I still
need to learn more about this. But it turned out much easier than I
as I thought it would be. The main issues are on how
to declare the Ada subprograms in C++, and how to make sure the way
the Ada subprogram is called matches the way it expects to be
called.
A C++ main calls an Ada procedure to update an integer. (I also
use C in this example just for testing.)
I also show the steps used to build the program, and few points at the end
about few things.
This was done on solaris 2.5, using gnat 3.04.
file main.cc
-------------
#include <iostream.h>
#include <stdio.h>
extern "C" { void Ada_Function(int*);
void adainit(); // this and adafinal are calls to ada
void adafinal(); // rtl to insure things are initialized
} // and finailized ok...
main()
{
int i=0;
adainit(); // call befor any other ada call
printf("This is a C printf ... \n");
cout<<"this is C++ cout..."<<endl;
cout<<" before calling Ada, i="<<i<<endl;
Ada_Function(&i);
cout<<" after calling Ada, i="<<i<<endl;
adafinal(); // call before program terminates
return 0;
}
file: ada_function.adb
----------------------
with Text_Io; use Text_Io;
procedure Ada_Function(I:in out integer) is
begin
Put_Line("This is Ada Put_Line ...");
Put_Line("Number passed in is" & Integer'Image(I));
I := I+1;
end;
pragma Export(C,Ada_Function,"Ada_Function");
Steps used to build main* are : (note: gcc here is the gcc that comes
with gnat 3.04. for the g++ include files, and libg++.a and
libstdc++.a libraries, those were obtained seperatly and build in different
directory. I found out for example that cc1plus* was needed to be under
2.7.2/ directory in the gnat 2.4 solaris installtion tree, but it was not,
so I copied that file from the 2.7.2/ directory under the tree that was build
seperatly for the 2.5 solaris. This way I was able to use gnat gcc to build
C++, without cc1plus* one can not build C++ files using the gcc that comes
with gnat 3.04-solaris 2.4.)
gcc -c main.cc -I/usr/local/netshare/lib/g++-include
gnatbind -n ada_function.ali
gnatlink -L/usr/local/netshare/lib ada_function.ali main.o \
-lg++ -lstdc++ -o main
...now run the program...
{95} main
This is a C printf ...
this is C++ cout...
before calling Ada, i=0
This is Ada Put_Line ...
Number passed in is 0
after calling Ada, i=1
few points I noticed:
1) In C++, one must declare the Ada procedure and functions as
C functions, else C++ will mangle the ada function names, and the
gnatlink step will fail as poor linker will not be able to resolve
the name. for example, if one do not use extern "C" {..}, and
then look at the object file generated, one sees :
$ nm -x main.o
main.o:
[Index] Value Size Type Bind Other Shndx Name
[5] |0x00000000|0x00000000|NOTY |GLOB |0x0 |UNDEF |Ada_Function__Fi
But after using the extern "C" {...} to declare the Ada procedure,
the function name is not changed by C++ :
$nm -x main.o
main.o:
[Index] Value Size Type Bind Other Shndx Name
[14] |0x00000000|0x00000000|NOTY |GLOB |0x0 |UNDEF |Ada_Function
Now, the function name matches that in the ada object file, and
the linker is a happy camper.
2) In the Ada procedure, defining Ada_function as
procedure Ada_Function(I:in out integer)
^^^^^
or
procedure Ada_Function(I:out integer)
^^^^
resulted in no difference in build or run results.
3) more about point 2: How to make sure that the way the Ada
subprogram is called from the C++ module matches that the way
Ada subprogram is defined in the Ada module?
For example, in the above example, in main.cc, one can change the
argument being passed to the Ada procedure from int* to char*, and rebuild
the C++ main.cc, link to the ada procedure, and no errors are
detected, untill the program is run.
So, it is important to "manually" make sure the way the Ada program
is called matches the way it is defined. Is there better way? ..
When calling C++ from C++, one uses common function prototypes (in
common headers) to make sure all modules agree on the function
signature, so that the way a function is called matches the way the is
defined. Similar idea is used when calling Ada from Ada. The Ada
compiler makes sure the formal and actual parameters agree.
But how to insure this when calling Ada from C++ ?
Nasser
==========================================================
Nasser Abbasi. Senior software engineer. C/C++/Solaris.
GeneAssist- a client/server application for Nucleic acid
and protein sequence search and analysis.
PE-Applied BioSystem division. nasser@apldbio.com
--
Nasser Abbasi. Senior software engineer. C/C++/Solaris.
GeneAssist- a client/server application for Nucleic acid
and protein sequence search and analysis.
PE-Applied BioSystem division. nasser@apldbio.com
next reply other threads:[~1996-06-12 0:00 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
1996-06-12 0:00 Nasser Abbasi [this message]
1996-06-13 0:00 ` on calling Ada from C/C++ Nasser Abbasi
1996-06-13 0:00 ` Robert Dewar
1996-06-13 0:00 ` Robert Dewar
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox