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=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,f0d9db8126fd91cb X-Google-Attributes: gid103376,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news2.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newsfeed00.sul.t-online.de!t-online.de!inka.de!peernews!news.belwue.de!newsfeed.arcor.de!newsspool1.arcor-online.net!news.arcor.de.POSTED!not-for-mail From: "Dmitry A. Kazakov" Subject: Re: Converting pointers to non nul-terminated C "strings" to Ada string Newsgroups: comp.lang.ada User-Agent: 40tude_Dialog/2.0.15.1 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Reply-To: mailbox@dmitry-kazakov.de Organization: cbb software GmbH References: Date: Sat, 14 Feb 2009 10:26:05 +0100 Message-ID: <9o91prwivma0$.1e4dd833ypxy1.dlg@40tude.net> NNTP-Posting-Date: 14 Feb 2009 10:26:05 CET NNTP-Posting-Host: 057901ea.newsspool2.arcor-online.net X-Trace: DXC=4bn_AGBQ1KEFJ3]dH>I?oEA9EHlD;3YcB4Fo<]lROoRA^YC2XCjHcbIbAX1NgmTjIBDNcfSJ;bb[EIRnRBaCd 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