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.8 required=5.0 tests=BAYES_00,INVALID_DATE autolearn=no autolearn_force=no version=3.4.4 Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!samsung!uakari.primate.wisc.edu!sdd.hp.com!hplabs!hpcc01!hpcuhb!hpcllla!hpclisp!defaria@hpclapd.HP.COM From: defaria@hpclapd.HP.COM (Andy DeFaria) Newsgroups: comp.lang.ada Subject: C Strings in Ada? Message-ID: <920024@hpclapd.HP.COM> Date: 4 Jun 90 22:45:44 GMT Organization: Hewlett-Packard Calif. Language Lab List-Id: I would like to create a small package that interfaces to some C code via a pragma INTERFACE and I have a question to all you Ada pros out there. What is the best way to represent C_Strings in Ada? C's notion of a string is a pointer to a char of undetermined length, terminated by a null character. Ada has a totally different notion of what a string is. I can see 3 instances where I need to use a "C_String": 1) As parameters to a subprogram call. 2) As a value returned from a function call. 3) As a part of a record passed to (or returned by) a function. I am concerned with usability and efficiency as I intend to reuse this package. I could declare an Ada string and pass the 'ADDRESS to the interfaced C code but then I need to append the null character before calling the routine in the package. I could have the package append the null character but this would require one or two heap allocations on every call and return which I consider a big drawback from the viewpoint of efficiency. I have tried defining this "C_String" as it is described to C, as an access to CHARACTER but with this representation I can not look at the value of the Ada string in the debugger because the debugger faithly shows me only the first character. I consider this a big drawback from the viewpoint of usability. And how should strings be described as part of a record structure? I can see three possiblities, none of which are ideal: (1) Represent C strings as access types to STANDARD.CHARACTER The pointer points to a null terminated string. Since this uses the same representation as C no conversions are necessary. I would then have to provide subprograms to convert regular Ada strings into this data type. Advantages: Speed, Efficiency Disadvantages: Only the first character is visible in the debugger, Need to call the conversion routines before making the call the package. No conversion is needed if the parameter itself was obtained from a previous call to one of my routines in the package or if the same value was used as a paramater from a previous call. (2) Represent the strings as Ada strings In this scheme, the caller would use only Ada strings and my package will always perform the conversion of the string into a null terminated string. Advantages: Ada-like, only one interpretation of a "string" needs to be considered by the users of the package. Disadvantanges: The heap manager has to be called not only to allocate strings, but also records that contain strings. Since there are now C versions of records and Ada versions of records, a subprogram should be provided to convert the C version of the record to the Ada version of the record. Also messier to implement and users of my package may come upon the C version of the record by chasing pointers within a record. (3) Represent the C strings as Ada strings, but ... In this scheme, the caller of my package should use Ada strings that are terminated with the null character thereby placing some responisbility on them. My package can then pass these strings directly to the C routines I'm interfacing to. If I discover that the caller was lazy and shucked his responsibility by not terminating the string with a null character, then I can do it for them and thereby incur the overhead of calling the heap manager only if the caller forgot to terminate the string with a null. When my package returns character strings, then I would have to allocate space for these strings by calling the heap manager but I would be giving the caller a string that they can in turn pass back to my package without additional heap manager overhead. Advantages: Compromise between the two other method presented. Heap manager overhead is incurred only when necessary. If strings that are contained in record structures are defined as access to Ada strings then the records are of identical size. Disadvantages: Does not solve the problem of strings contained within records. Since there is a C version of the record and an Ada version, I still have the problems of providing conversion routines. 4) Combine methods 1 & 2. This scheme would basically combine methods 1 & 2 by using Ada's overloaded function call capability. Thus the caller could use either method. Advantages: Caller could use the Ada-like calls while debugging and migrate to the faster C-like calls. Disadvantages: Much more work involved for me in writing the package. Still have a problem with strings inside of records. Once the user migrates to the faster C-like calls it is hard to debug because they can't look at any "C_Strings". Requires that they change their code to use "Ada Strings" and recompile. What do you think? How would you implement "C_Strings" in Ada?