
Ok,
I used this advice:
http://www.haskell.org/haskellwiki/GHC/Using_the_FFI#Importing_C_functions_t...
to make 'xmlFree' callable from Haskell.
I was completly wrong in my first post...
I do apologize.
On Sun, Nov 29, 2009 at 8:56 PM, El Barto
Thanks for your help & time,
I checked the C API documentation: http://xmlsoft.org/html/libxml-xmlreader.html#xmlTextReaderValue "The result must be deallocated with xmlFree()"
I pushed the sources here: http://github.com/gwenn/libxml-reader
My problem is with the function at line 249 in Text.XML.LibXML.XmlReader To make it work, I have to comment out the line where xmlFree is called.
-- xmlChar * xmlTextReaderValue(xmlTextReaderPtr reader) -- Returns:the string or NULL if not available. The result must be deallocated with xmlFree() foreign import ccall unsafe "xmlreader.h xmlTextReaderValue" c_xmlTextReaderValue :: Ptr XmlTextReader -> IO (CString) value :: (MonadIO m) => XmlReader -> m (Maybe B.ByteString) value (XmlReader reader_fp) = liftIO $ withForeignPtr reader_fp $ \reader_ptr -> do cstr <- c_xmlTextReaderValue reader_ptr fromPtr B.packCString cstr c_xmlFree
fromPtr :: (Ptr a -> IO b) -> Ptr a -> (Ptr a -> IO ()) -> IO (Maybe b) fromPtr c2h ptr free | ptr == nullPtr = return Nothing | otherwise = do r <- c2h ptr free ptr -- FIXME return (Just r)
May be the binding to xmlFree is wrong? foreign import ccall unsafe "xmlreader.h xmlFree" c_xmlFree :: Ptr a -> IO ()
To test, you will need libxml2-dev: $ runhaskell Setup configure --extra-include-dirs=/usr/include/libxml2/ $ runhaskell Setup build $ ./dist/build/Test/Test
C functions are described here: http://xmlsoft.org/html/libxml-xmlreader.html And here: http://xmlsoft.org/html/libxml-globals.html
Regards.
On Sun, Nov 29, 2009 at 7:02 PM, Duncan Coutts < duncan.coutts@googlemail.com> wrote:
On Sun, 2009-11-29 at 18:00 +0100, El Barto wrote:
Hello, I get a segfault when I do str <- peekCString ptr free ptr return (Just str)
As Thomas says, you've not really given us enough info here.
I'll make some guesses and observations anyway :-)
But not when I don't free the C pointer.
Are you sure the C code does not also free the memory? That would lead to a double-free which can easily manifest as a segfault.
I also get the same behaviour with ByteString.packCString...
That's pretty odd since packCString does not free the C string, it makes a copy. I suppose it could possibly segfault if your C string was not actually null terminated (as C strings must be).
There are also variants that do not copy, such as unsafePackMallocCString. See the docs for a description.
Could you please tell me if the memory is correctly freed by GHC when I don't do it myself? And how can I specify a custom free function (i.e. xmlFree function in libxml2)?
See the documentation for ForeignPtr.
Maybe I should use a data type with two fields : the String/ByteString and the ForeignPtr to the CString?
Is your C String supposed to be freed using the C free() function, or is it supposed to be freed using xmlFree() or something?
Duncan