FFI foreignPtr construction

Hello, since the last time I think that I understand how to manage Ptr, now I woud like to masterize the ForeignPtr in order to let haskell managed the life of my C objects. So I try to create a Geoemtry object like this. -- data Geometry newtype Geometry = Geometry (Ptr Geometry) deriving (Show, Storable) newGeometry :: Factory -> ForeignPtr Geometry newGeometry f = unsafePerformIO $ do geometry <- c_hkl_factory_create_new_geometry f newForeignPtr c_hkl_geometry_free geometry foreign import ccall safe "hkl.h hkl_factory_create_new_geometry" c_hkl_factory_create_new_geometry :: Factory -> IO (Geometry) foreign import ccall safe "hkl.h &hkl_geometry_free" c_hkl_geometry_free :: FunPtr (Geometry -> IO ()) the C signature are HKLAPI HklGeometry *hkl_factory_create_new_geometry(const HklFactory *self) HKL_ARG_NONNULL(1); HKLAPI void hkl_geometry_free(HklGeometry *self) HKL_ARG_NONNULL(1); But when I try to compile this code, I get this error message 1 of 1] Compiling Hkl.C ( src/Hkl/C.hs, dist/build/Hkl/C.o ) src/Hkl/C.hs:51:33: Couldn't match type ‘Geometry’ with ‘Ptr Geometry’ Expected type: GHC.ForeignPtr.FinalizerPtr Geometry Actual type: FunPtr (Geometry -> IO ()) In the first argument of ‘newForeignPtr’, namely ‘c_hkl_geometry_free’ In a stmt of a 'do' block: newForeignPtr c_hkl_geometry_free geometry src/Hkl/C.hs:51:53: Couldn't match expected type ‘Ptr Geometry’ with actual type ‘Geometry’ In the second argument of ‘newForeignPtr’, namely ‘geometry’ In a stmt of a 'do' block: newForeignPtr c_hkl_geometry_free geometry I do not understand what is wrong in my code thanks if you can help Frederic

Hi, You can try something like this (not tested): data Geo = Geo -- this represents the HklGeometry C structure (for clarity) newtype Geometry = Geometry (ForeignPtr Geo) deriving (Show, Storable) newGeometry :: Factory -> IO Geometry newGeometry f = do -- avoid unsafePerformIO geometry <- c_hkl_factory_create_new_geometry f Geometry <$> newForeignPtr c_hkl_geometry_free geometry foreign import ccall safe "hkl.h hkl_factory_create_new_geometry" c_hkl_factory_create_new_geometry :: Factory -> IO (Ptr Geo) foreign import ccall safe "hkl.h &hkl_geometry_free" c_hkl_geometry_free :: FunPtr (Ptr Geo -> IO ()) 2016-01-27 13:50 GMT+01:00 PICCA Frederic-Emmanuel < frederic-emmanuel.picca@synchrotron-soleil.fr>:
Hello,
since the last time I think that I understand how to manage Ptr, now I woud like to masterize the ForeignPtr in order to let haskell managed the life of my C objects. So I try to create a Geoemtry object like this.
-- data Geometry newtype Geometry = Geometry (Ptr Geometry) deriving (Show, Storable)
newGeometry :: Factory -> ForeignPtr Geometry newGeometry f = unsafePerformIO $ do geometry <- c_hkl_factory_create_new_geometry f newForeignPtr c_hkl_geometry_free geometry
foreign import ccall safe "hkl.h hkl_factory_create_new_geometry" c_hkl_factory_create_new_geometry :: Factory -> IO (Geometry)
foreign import ccall safe "hkl.h &hkl_geometry_free" c_hkl_geometry_free :: FunPtr (Geometry -> IO ())
the C signature are
HKLAPI HklGeometry *hkl_factory_create_new_geometry(const HklFactory *self) HKL_ARG_NONNULL(1);
HKLAPI void hkl_geometry_free(HklGeometry *self) HKL_ARG_NONNULL(1);
But when I try to compile this code, I get this error message
1 of 1] Compiling Hkl.C ( src/Hkl/C.hs, dist/build/Hkl/C.o )
src/Hkl/C.hs:51:33: Couldn't match type ‘Geometry’ with ‘Ptr Geometry’ Expected type: GHC.ForeignPtr.FinalizerPtr Geometry Actual type: FunPtr (Geometry -> IO ()) In the first argument of ‘newForeignPtr’, namely ‘c_hkl_geometry_free’ In a stmt of a 'do' block: newForeignPtr c_hkl_geometry_free geometry
src/Hkl/C.hs:51:53: Couldn't match expected type ‘Ptr Geometry’ with actual type ‘Geometry’ In the second argument of ‘newForeignPtr’, namely ‘geometry’ In a stmt of a 'do' block: newForeignPtr c_hkl_geometry_free geometry
I do not understand what is wrong in my code
thanks if you can help
Frederic _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

Thanks for your help I end up with this code which I find quite elegant :) -- data Geometry data HklGeometry newtype Geometry = Geometry (ForeignPtr HklGeometry) deriving (Show) newGeometry :: Factory -> IO Geometry newGeometry f = Geometry <$> (c_hkl_factory_create_new_geometry f >>= newForeignPtr c_hkl_geometry_free) foreign import ccall unsafe "hkl.h hkl_factory_create_new_geometry" c_hkl_factory_create_new_geometry :: Factory -> IO (Ptr HklGeometry) foreign import ccall unsafe "hkl.h &hkl_geometry_free" c_hkl_geometry_free :: FunPtr (Ptr HklGeometry -> IO ()) Cheers Frederic
participants (2)
-
PICCA Frederic-Emmanuel
-
Sylvain Henry