Bug in GHC's Garbage Collection? (fwd) - C Strings

Christian Lescher christian@lescher.de
Mon, 13 Nov 2000 19:24:14 +0100


Hi Simon,

> > 1) How to convert the Haskell string to a C string? - There's
> > a function
> >
> >   packCString#      :: [Char]          -> ByteArray#
> >   packCString# str = case (packString str) of { ByteArray _ _ bytes ->
> > bytes }
> >
> > in CStrings.lhs / PrelPack.lhs, which I probably have to use.
>
> Yes (but use packString rather than packString#).

Okay, so I have use: packString :: [Char] -> ByteArray Int
btw: what's the difference between packString and packCString then?

> > 2) How to pass a pointer (Addr) of the converted string back
> > to the outside
> > world?
>
> You can pass the ByteArray directly to a foreign imported function (which
> *must* be declared unsafe - you can't pass ByteArrays to safe ccalls).

I think, here the context got lost: I want to expose a Haskell function with
a string result rather than calling a C function from Haskell.


> > 3) Who is responsible for freeing the memory of the string result? I
> > suppose this should be done outside. But what to do that GHC's garbage
> > collection doesn't free it automatically?
>
> The ByteArray is freed automatically by GHC's garbage collector.  If you
> need something more permanent, use malloc/free and the functions from
> Storable to do the marshalling.

For instance, how would you define a function like

  revstr :: String -> String
  revstr s = reverse s

for foreign export?

(The conversion of the string argument I handled like this:)

strlength  :: Addr -> IO Int
strlength cstr = do
  s <- unpackCStringIO cstr
  return (length s)

foreign export stdcall strlength :: Addr -> IO Int

Cheers, Christian

P.S. I think, some information on the handling of typical string conversion
problems would be an interesting topic for GHC's user's manual, too.