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 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: a07f3367d7,fb17569fccf2604b,start X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!postnews.google.com!x6g2000prc.googlegroups.com!not-for-mail From: Jerry Newsgroups: comp.lang.ada Subject: Trouble writing Ada callback from C Date: Fri, 11 Sep 2009 00:57:09 -0700 (PDT) Organization: http://groups.google.com Message-ID: NNTP-Posting-Host: 75.172.194.61 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 X-Trace: posting.google.com 1252655829 23735 127.0.0.1 (11 Sep 2009 07:57:09 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Fri, 11 Sep 2009 07:57:09 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: x6g2000prc.googlegroups.com; posting-host=75.172.194.61; posting-account=x5rpZwoAAABMN2XPwcebPWPkebpwQNJG User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-US) AppleWebKit/528.16+(KHTML, like Gecko, Safari/528.16) OmniWeb/v622.8.0,gzip(gfe),gzip(gfe) Xref: g2news2.google.com comp.lang.ada:8283 Date: 2009-09-11T00:57:09-07:00 List-Id: I have a problem with writing an Ada procedure, used as a callback from C, in which one of the arguments is an output char * (in the C version). The actual length of the returned "string" isn't known at calling time, even though the caller apparently allocates 40 characters (see below). However, the actual number of characters returned by the C version is less than 40. My problem is how to pass probably a char_array back out which is the correct length, but which length is not known at the time the Ada callback is called from C. Here is a highly shortened version of one of many things that I have tried. I have not compiled or run this shortened version, but I believe that it contains the essence of the longer version: procedure geolocation_labeler (label : out char_array; a_length : size_t); pragma Convention(C, geolocation_labeler); -- Highly shortened version. procedure geolocation_labeler (label : out char_array; a_length : size_t) is direction_label : Unbounded_String; begin Put_Line("a_length = " & a_length'img); -- for testing direction_label := To_Unbounded_String(" N"); -- not always length 2 label := To_C(To_String(direction_label), False); end geolocation_labeler; Of course, this fails with: raised CONSTRAINT_ERROR : blabla.adb:xxx length check failed Note that the Put_Line always prints 40, passed by the C caller. Here is a highly shortened version of the C callback. Note that PLINT is just an integer. /* Highly shortened version.*/ void geolocation_labeler(char *label, PLINT length) { const char *direction_label; direction_label = " N"; snprintf(label, length, "%s", direction_label); printf(label); /* for testing */ } The printf(label) returns exactly N (in this case) without \n. In particular, it is only 2 characters, not 40. (Presumably, length has a value of 40 here as well, although I have not tested that assumption.) I have tried things such as changing the type of label in the argument list then declaring e.g. label_as_char_array : aliased char_array := (0 .. whatever => ' '); label_as_char_array_ptr : char_array_access; then building the string in label_as_char_array, then doing label_as_char_array_ptr := label_as_char_array'Unchecked_Access; and then returning label_as_char_array_ptr. That also didn't work. So how do I mimic the char * behavior of C when the length of the output array is not known at call time? Jerry