3.11.3.3 A Simple Example

The following example, provided as part of the GNAT examples, shows how to achieve procedural interfacing between Ada and C++ in both directions. The C++ class A has two methods. The first method is exported to Ada by the means of an extern C wrapper function. The second method calls an Ada subprogram. On the Ada side, the C++ calls are modelled by a limited record with a layout comparable to the C++ class. The Ada subprogram, in turn, calls the C++ method. So, starting from the C++ main program, the process passes back and forth between the two languages.

Here are the compilation commands:

$ gnatmake -c simple_cpp_interface
$ g++ -c cpp_main.C
$ g++ -c ex7.C
$ gnatbind -n simple_cpp_interface
$ gnatlink simple_cpp_interface -o cpp_main --LINK=g++ -lstdc++ ex7.o cpp_main.o

Here are the corresponding sources:

//cpp_main.C

#include "ex7.h"

extern "C" {
  void adainit (void);
  void adafinal (void);
  void method1 (A *t);
}

void method1 (A *t)
{
  t->method1 ();
}

int main ()
{
  A obj;
  adainit ();
  obj.method2 (3030);
  adafinal ();
}
//ex7.h

class Origin {
 public:
  int o_value;
};
class A : public Origin {
 public:
  void method1 (void);
  void method2 (int v);
  A();
  int   a_value;
};
//ex7.C

#include "ex7.h"
#include <stdio.h>

extern "C" { void ada_method2 (A *t, int v);}

void A::method1 (void)
{
  a_value = 2020;
  printf ("in A::method1, a_value = %d \\n",a_value);
}

void A::method2 (int v)
{
   ada_method2 (this, v);
   printf ("in A::method2, a_value = %d \\n",a_value);
}

A::A(void)
{
   a_value = 1010;
  printf ("in A::A, a_value = %d \\n",a_value);
}
-- simple_cpp_interface.ads
with System;
package Simple_Cpp_Interface is
   type A is limited
      record
         Vptr    : System.Address;
         O_Value : Integer;
         A_Value : Integer;
      end record;
   pragma Convention (C, A);

   procedure Method1 (This : in out A);
   pragma Import (C, Method1);

   procedure Ada_Method2 (This : in out A; V : Integer);
   pragma Export (C, Ada_Method2);

end Simple_Cpp_Interface;
-- simple_cpp_interface.adb
package body Simple_Cpp_Interface is

   procedure Ada_Method2 (This : in out A; V : Integer) is
   begin
      Method1 (This);
      This.A_Value := V;
   end Ada_Method2;

end Simple_Cpp_Interface;