From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,51114679936bf41a X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news3.google.com!news4.google.com!news.glorb.com!proxad.net!cleanfeed2-a.proxad.net!nnrp9-2.free.fr!not-for-mail From: Yves Bailly Subject: Re: Calling C++ from Ada Date: Sun, 14 May 2006 10:59:50 +0200 User-Agent: Pan/0.14.2.91 (As She Crawled Across the Table (Debian GNU/Linux)) Message-Id: Newsgroups: comp.lang.ada References: MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit Organization: Guest of ProXad - France NNTP-Posting-Date: 14 May 2006 11:00:01 MEST NNTP-Posting-Host: 81.56.171.53 X-Trace: 1147597201 nnrp9-2.free.fr 4697 81.56.171.53:40896 X-Complaints-To: abuse@proxad.net Xref: g2news2.google.com comp.lang.ada:4241 Date: 2006-05-14T11:00:01+02:00 List-Id: 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 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