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 10:26:05 +0100
Date: 2009-02-14T10:26:05+01:00	[thread overview]
Message-ID: <9o91prwivma0$.1e4dd833ypxy1.dlg@40tude.net> (raw)
In-Reply-To: df6e5b77-2d9f-4428-9e34-5f63bea39816@u13g2000yqg.googlegroups.com

On Fri, 13 Feb 2009 22:58:55 -0800 (PST), xorquewasp@googlemail.com wrote:

> I have some C code that returns a pointer to a buffer of
> "data" (not a string, just raw data) and also returns the
> size of the buffer:
> 
> void
> get_data (char **ptr, int *size);
> 
> int size;
> char *ptr;
> 
> get_data (&ptr, &size);
> 
> The code is part of a library that I don't control, so I can't
> change the interface.
> 
> I've defined the Ada equivalent as:
> 
>     package CS renames Interfaces.C.Strings;
>     package C renames Interfaces.C;
> 
>     procedure memory_data
>       (data   : out CS.chars_ptr;
>        size   : out C.int);
>     pragma Import (C, memory_data, "get_data");
> 
> This works correctly, however I'm having trouble converting
> the chars_ptr type to an Ada string given that it's not nul-
> terminated.
> 
> Attempts to do the following:
> 
> return CS.Value (Item => data, Length => size);
> 
> ... results in a String as long as the position of the first nul in
> the
> C string (the position is inevitably less than the length of the
> string).
> 
> Is it possible to properly convert unterminated C strings or do I
> need to start messing about with raw System.Address types?

I would suggest to use Interfaces.C.Pointers instead of
Interfaces.C.Strings:

with Interfaces.C;           use Interfaces.C;
with Interfaces.C.Pointers;

package Char_Ptrs is
   new Interfaces.C.Pointers (size_t, char, char_array, Nul);
use Char_Ptrs;

function Get return String is
   procedure memory_data
             (  data   : out Pointer;
                size   : out ptrdiff_t  -- Really int as in your example?
             );
   pragma Import (C, memory_data, "get_data");
   Data : Pointer;
   Size : ptrdiff_t;
begin
   memory_data (Data, Size);
   return To_Ada (Value (Data, Size), False);
end Get;

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.

Yet another issue. It is not so frequent that C API allocated a data buffer
and returned it to the caller, as your example suggests. Usually it is the
caller who passes an array to the C callee specifying its maximal capacity.
In this case the code should be different. In the former case, the question
arise, who is responsible for feeing the buffer. Does Data point to some
statically allocated piece of memory inside C library, or else you have to
free Data after converting it to Ada array?

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



  reply	other threads:[~2009-02-14  9:26 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 [this message]
2009-02-14 10:38   ` xorquewasp
2009-02-14 11:16     ` Dmitry A. Kazakov
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