[comp.lang.ada] C strings in Ada

emery@D74SUN.MITRE.ORG (David Emery) (06/07/90)

>What is the best way to represent C_Strings in Ada?  

The right solution is to keep all strings in the Ada program as Ada
strings, and change them to/from C strings at the point of interface
to C.  (i.e.  within the body of Ada_routine_calling_c).  This
preserves the Ada abstractions, and makes all the Ada things work just
fine (e.g. 'IMAGE, which returns an Ada string).  The only other
alternative (that makes sense to me) is to make C_STRING a private
type derived from System.address, but you won't be able to do anything
useful in the debugger with this.

How you do this conversion is very machine dependent, but here's my
tricks that work on Verdix (Sun 3) and Meridian (IBM PC):

	procedure to_c (str : string) 
	is
	  procedure c_routine (addr : system.address);
          pragma interface (C, c_routine);	-- (void) c_routine(s)
						-- char * s;
	  c_string : constant string := str & Ascii.NUL;
	begin
	  c_routine(c_string(c_string'first)'address);
	end to_c;

	function from_c  
	    return string
	is
	    function c_function			
		return System.address;		
	    pragma interface (C, c_function);	-- char * c_function
	    function strlen (addr : System.address)
		return integer;
	    pragma interface (C, strlen);	-- the C function of
						-- the same name
	    addr_from_c : System.address;
	 begin
	    addr_from_c := c_function;
	    declare
	      answer : string(1..strlen(addr_from_c);
	      for answer'address use at addr_from_c;
	    begin
	      return answer;
	    end;
  	 end from_c;

Hopefully what's going here is obvious, if not let me know and I'll
send more information.

				dave emery
				emery@aries.mitre.org