I noticed that I kept running up against a slightly obscure abiguity in
HDirect while trying to simulate the correct marshalling routine for an
array of strings. It turns out that the abiguity stems from the two
semantically different ways a string can be represented in C. That is, a
string can be defined either as an array of characters or as a pointer
to a character. Where this causes problems is when I come across the
type, "Ptr String". If a "string" is defined as an array of chars, then
Ptr String would be a pointer to an array, or rather the first char of
the array. In this case Ptr String is the same as Ptr Char. On the other
hand, if a "string" is defined as a pointer to a char, then Ptr String
would be a pointer to a pointer to a char, or Ptr (Ptr Char).

In HDirect.lhs, the array semantic is used in all of the functions that
explicitly deal with strings. However, when I tried to deal with an
array of strings, C treats such a beast as an array of pointers to
chars; not an array of arrays. This lead me to some (initially
confusing) problems I tried to use the straightforward approach of using
marshalllist and supplying a list of strings. The main point of
confusion was marshalllist's polymorphic parameter, Ptr a -> a -> IO ().
In this particular case, this parameter's type is instantiated to Ptr
String -> String -> IO (). However, this *should* be Ptr (Ptr Char) ->
String -> IO () in order to correctly match the way C stores arrays of
strings.

Obviously, I've identified the problem and have been able to work around
it. The point of this message is to share some observations that may not
have been noticed by others yet. I realize that (Ptr String) = (Ptr
Char) = (Ptr (Ptr Char)) since they are all really just Addr. But the if
the point of defining the type of a Ptr is to add clarity, I don't think
that the use of "Ptr String" adds much clarity.

Rambling on,
        Michael Hobbs

Reply via email to