A Simple Example (GNAT User’s Guide for Native Platforms)

#### 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, execution 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;