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.