comp.lang.ada
 help / color / mirror / Atom feed
From: Yves Bailly <kafka.fr@laposte.net>
Subject: Re: Calling C++ from Ada
Date: Sun, 14 May 2006 10:59:50 +0200
Date: 2006-05-14T11:00:01+02:00	[thread overview]
Message-ID: <pan.2006.05.14.08.59.44.155698@laposte.net> (raw)
In-Reply-To: e6qhj3-3bp.ln1@newserver.thecreems.com

On Sat, 13 May 2006 15:55:38 -0400, Jeffrey Creem wrote:
> If you are thinking of doing something yourself perhaps you should look 
> at adding an Ada output module for SWIG.
> Looking at some of the other language output modules it appears that it 
> is a reasonably small project.

Interesting. I'll dig into this, it seems promising.

Sorry if I'm boring everyone here, but I would like to submit some
thoughts on a way to call C++ from Ada, through a C wrapper, avoiding
too much dynamic memory allocations.

The basic idea is to reserve the needed space on the Ada side, then to
use the placement "new" on the C++ side. 

A generic holder is declared this way :
--8<-----8<-----8<-----8<-----8<---
   package C renames Interfaces.C ;
   type Cpp_Holder(Size: C.size_t) is tagged limited
   record
      holder: C.char_array(1..Size) ;
   end record ;
--8<-----8<-----8<-----8<-----8<---

Now assume you want to use the standard std::string class from Ada.
This could be done like this :
--8<-----8<-----8<-----8<-----8<---
   Std_String_Size: constant C.size_t ; -- imported needed size
   pragma Import(C, Std_String_Size, "Std_String_Size") ;
   type Std_String is 
      new Cpp_Holder(Size=>Std_String_Size) with null record;
   -- imported C function to create an empty string
   procedure Std_String_String(where: System.Address) ;
   pragma Import(C, 
                 Std_String_String, 
                 "Std_String_String") ;
   -- Ada-side creation procedure
   procedure Create(ss: in out Std_String) is
   begin
      Std_String_String(ss.holder(1)'Address) ;
   end Create ;
--8<-----8<-----8<-----8<-----8<---

The C wrapper would be :

--8<-----8<-----8<-----8<-----8<---
   // std_string_wrapper.h
   #include <string>
   extern "C"
   {
      extern const size_t Std_String_Size ;
      void Std_String_String(std::string* where) ;
   }

   // std_string_wrapper.cpp
   #include "std_string_wrapper.h"
   extern "C"
   {
      const size_t Std_String_Size = sizeof(std::string) ;
      void Std_String_String(std::string* where)
      {
         new (where) std::string ;
      }
   }
--8<-----8<-----8<-----8<-----8<---

If you're interested and willing to give advices or comments, I've
build a more detailed example :
http://kafka-fr.hd.free.fr/~yves/cpp_holder.tar.bz2

It can be build using GNAT with
gprmake -P std_string.gpr
...tested using GCC 4.2.0 as of 20060512. The trivial test program
works fine, as far as I can tell for now.

Is this approach too nasty ? Is it more or less portable ?

Best regards,

           Yves Bailly




  reply	other threads:[~2006-05-14  8:59 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-05-13 14:48 Calling C++ from Ada Yves Bailly
2006-05-13 17:02 ` Jeffrey Creem
2006-05-13 19:08   ` Yves Bailly
2006-05-13 19:55     ` Jeffrey Creem
2006-05-14  8:59       ` Yves Bailly [this message]
2006-05-14 13:39         ` Jeffrey Creem
2006-05-14 18:38         ` Jeffrey R. Carter
2006-05-15 15:24       ` rodkay
2006-05-15 16:23         ` Jeffrey Creem
2006-05-16  2:14         ` Gene
2006-05-16  4:31           ` rodkay
2006-05-16 11:47             ` Jeffrey Creem
2006-05-17  4:53               ` rodkay
2006-05-17  6:05                 ` Martin Krischik
2006-05-25  5:34                   ` rodkay
2006-05-25 11:29                     ` Alex R. Mosteo
2006-05-29  3:43                       ` Gene
2006-05-29 14:53                         ` rodkay
2006-05-29 17:48                         ` Martin Krischik
2006-05-13 22:38     ` Craig Carey
replies disabled

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