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: 103376,ea88e33ca617708 X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII Received: by 10.68.59.229 with SMTP id c5mr4039866pbr.6.1321669125448; Fri, 18 Nov 2011 18:18:45 -0800 (PST) Path: h5ni7797pba.0!nntp.google.com!news1.google.com!postnews.google.com!y15g2000prl.googlegroups.com!not-for-mail From: Adam Beneschan Newsgroups: comp.lang.ada Subject: Re: Calling Ada Procedure from C - how to handle a char ptr/array Date: Fri, 18 Nov 2011 18:16:55 -0800 (PST) Organization: http://groups.google.com Message-ID: References: <8e5541a3-cdd5-40af-a6fd-f7539ee61326@l19g2000yqc.googlegroups.com> NNTP-Posting-Host: 66.126.103.122 Mime-Version: 1.0 X-Trace: posting.google.com 1321669125 13467 127.0.0.1 (19 Nov 2011 02:18:45 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Sat, 19 Nov 2011 02:18:45 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: y15g2000prl.googlegroups.com; posting-host=66.126.103.122; posting-account=duW0ogkAAABjRdnxgLGXDfna0Gc6XqmQ User-Agent: G2/1.0 X-Google-Web-Client: true X-Google-Header-Order: ARLUEHNKC X-HTTP-UserAgent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; WOW64; Trident/4.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.5.21022; .NET CLR 3.5.30729; .NET CLR 3.0.30618; .NET4.0C),gzip(gfe) Xref: news1.google.com comp.lang.ada:18977 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Date: 2011-11-18T18:16:55-08:00 List-Id: On Nov 18, 11:40=A0am, awdorrin wrote: > What would be the recommended way to pass a C char pointer or char > array into an Ada function or procedure that will be called from a C > program? > > After reading through the Interfaces.C.* packages, I'm assuming I > could do something like this: > > In my Ada procedure: > > procedure Get_Text( s : out Interfaces.C.char_array) is > =A0 Label : String(1..8) > begin > =A0 Label(1..8) =3D=3D "12345678"; > =A0 S :=3D Interfaces.C.To_C(Label); > =A0end; Since you seem to be pretty new to Ada, I think you may have some misconceptions about how arrays work; so it might be useful to go over some basics. Array objects (this includes Strings) have bounds. Once the bounds are set for an object, they don't change. For Example, Label has the bounds 1..8 since you've declared it that way. You can't make Label shorter or longer by saying, for instance, Label :=3D "123456"; This will get you a Constraint_Error. S also has bounds. Since S is a parameter with an unconstrained array type, the bounds of S are determined by whatever parameter gets passed when Get_Text is called. (That's why it's a problem when it's called from C, because C code won't know that it's supposed to give any bounds to Get_Text.) But whatever the bounds are of the parameter are, they won't change; you can't change the bounds, or make S longer or shorter, by assigning to it. That means that in your statement: S :=3D Interfaces.C.To_C (Label); The right-hand side will be an array with 9 characters (since Label has 8, and To_C appends a NUL character). This statement will therefore work only if S's bounds are such that S will have exactly 9 characters. (I.e. if S's bounds are (1..9), (3..11), (100..108), etc.) Otherwise it will raise Constraint_Error. By the way, that applies to OUT parameters just as well as IN and IN OUT parameters. For an unconstrained array, OUT means that the data in the array will be set by the procedure. But the *bounds* of the array parameter are still input to the procedure, not output from it, and the procedure can't change them. If you need to set a portion of S, you need to use a slice on the left: S (S'First .. S'First + Label'Length) :=3D Interfaces.C.To_C (Label); which takes advantage of the knowledge that To_C returns a string whose length is Label'Length + 1. Or there are operations in Ada.Strings.Fixed to help with this: Ada.Strings.Fixed.Overwrite (S, S'First, Interfaces.C.To_C (Label)); Hope this helps, -- Adam