[MLton] passing a const char **

Matthew Fluet fluet at tti-c.org
Tue Dec 12 19:55:09 PST 2006


> I need to call a C function that takes as an argument an array of strings
> (with type const char **).  Unfortunately, trying to import the function
> with a "string vector" argument type doesn't work.  Is there a good reason
> for this restriction?  

If ML object pointers are not represented the same way as C pointer, 
then "string vector" doesn't have the same representation as "const char 
**".  This is an issue on 64bit systems with smaller ML object pointers. 
  It is reasonable to perform the constant time operation of lifting ML 
object pointers to C object pointers for the outermost FFI types, but it 
isn't constant overhead to coerce a vector of ML object pointers to a 
vector of C pointers, so I don't think it is the right design decision 
to support it.

 > Am I going to have to malloc the strings to pass
> them as arguments?

We need to handle the "const char **" idiom for exece/execp.  Here is my 
solution:

On the ML side, concatenate all the strings together into a single 
vector.  This isn't as expensive as it sounds, since one normally needs 
to add a null-terminator to all the ML strings before throwing it over 
to the C side.  Also on the ML side, allocate a C_Pointer.t array and a 
C_Size.t vector (although, perhaps the latter should be C_Ptrdiff.t). 
The C_Pointer.t array is of the same size as the number of strings, and 
is initialized to null.  the C_Size.t vector is also of the same size as 
the number of strings, and is initialized to offsets into the 
concatenated string that correspond to the beginning of each string.

This code can be found in the CUtil.StringVector structure:
http://mlton.org/cgi-bin/viewsvn.cgi/mlton/trunk/basis-library/util/CUtil.sml?rev=4898&view=auto

On the C side, fill in the C_Pointer.t array with the C pointers 
corresponding to the base of the concatenated string plus the offset.

This code, for Posix.Process.exece, can be found at:
http://mlton.org/cgi-bin/viewsvn.cgi/mlton/trunk/runtime/basis/Posix/Process/exece.c?rev=4898&view=auto

I'll admit that it isn't as clean a solution as I would like, and 
perhaps it is overkill to handle mixed pointer representations.





More information about the MLton mailing list