comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Converting pointers to non nul-terminated C "strings" to Ada string
Date: Sat, 14 Feb 2009 12:16:02 +0100
Date: 2009-02-14T12:16:03+01:00	[thread overview]
Message-ID: <1tbswd6ooo8u1.1jl2rgy3nq0lq$.dlg@40tude.net> (raw)
In-Reply-To: 6948ef0c-ce70-4330-ba2f-313d9b6ff6d5@l16g2000yqo.googlegroups.com

On Sat, 14 Feb 2009 02:38:35 -0800 (PST), xorquewasp@googlemail.com wrote:

> Dmitry A. Kazakov wrote:
>>
>> I would suggest to use Interfaces.C.Pointers instead of
>> Interfaces.C.Strings:
> 
> That does mean going outside of the RM, which is a bit unfortunate.
> I'll keep it in mind, however.

What do you mean by that? Interfaces.C.Pointers is a part of the standard
Ada library.

>> Are you sure that get_data is char **, int * rather than void **, size_t *?
>> In the latter case I would consider Storage_Array instead of String on the
>> Ada side.
> 
> Well, the C function parameters are defined as char **, int * but do have
> a meaning closer to void **, size_t *. Storage_Array is probably more
> appropriate, as you state. That still leaves the question of
> converting from an address or access type to an unconstrained array (can't pass an
> unconstrained array or access to an unconstrained array to C code).

One technique is to declare a huge flat array:

   type Never_Instantiate_Me is array (size_t'range) of char;
   pragma Convention (C, Never_Instantiate_Me);

or else simply:

   subtype Never_Instantiate_Me is char_array (size_t'range);

Never_Instantiate_Me will have no dope.

   type Never_Instantiate_Me_Ptr is access all Never_Instantiate_Me;
   pragma Convention (C, Never_Instantiate_Me_Ptr);;

Then you go:

   function Get return String is
      procedure memory_data
                (  data   : out Never_Instantiate_Me_Ptr;
                   size   : out size_t
                );
      pragma Import (C, memory_data, "get_data");
      Data : Never_Instantiate_Me_Ptr;
      Size : size_t;
   begin
      memory_data (Data, Size);
      if Size = 0 then
         return "";
      else
         return
            To_Ada
            (  Data (size_t'First..size_t'First + Size - 1),
               False
            );
      end if;
   end Get;

Note Size = 0 check. When Size is zero, there is no way to construct an
empty char_array since size_t is modular.
 
-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



  reply	other threads:[~2009-02-14 11:16 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-02-14  6:58 Converting pointers to non nul-terminated C "strings" to Ada string xorquewasp
2009-02-14  9:26 ` Dmitry A. Kazakov
2009-02-14 10:38   ` xorquewasp
2009-02-14 11:16     ` Dmitry A. Kazakov [this message]
2009-02-14 11:37       ` xorquewasp
2009-02-14  9:27 ` Hibou57 (Yannick Duchêne)
2009-02-14 10:41   ` xorquewasp
2009-02-15 17:44     ` Georg Bauhaus
2009-02-14 11:47   ` Jacob Sparre Andersen
2009-02-14 14:25     ` Hibou57 (Yannick Duchêne)
2009-02-14  9:28 ` sjw
2009-02-14  9:33 ` likai3g
replies disabled

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