
Hello, Here the signature of one of my C function -- hkl.h -- typedef struct _HklFactory HklFactory; HKLAPI HklFactory **hkl_factory_get_all(size_t *n) HKL_ARG_NONNULL(1); HKLAPI HklFactory *hkl_factory_get_by_name(const char *name, GError **error) HKL_ARG_NONNULL(1) HKL_WARN_UNUSED_RESULT; HKLAPI const char *hkl_factory_name_get(const HklFactory *self) HKL_ARG_NONNULL(1); HKLAPI HklGeometry *hkl_factory_create_new_geometry(const HklFactory *self) HKL_ARG_NONNULL(1); HKLAPI HklEngineList *hkl_factory_create_new_engine_list(const HklFactory *self) HKL_ARG_NONNULL(1); I will focuss for now only the get_all method. As you can see even for the C client of my API HklFactory is an opac struct This get_all method return an array of (HklFactory *) and get the size of the array via the n parameter. So I am trying to use this API from haskell with the foreign system and return a [HklFactory] import Foreign (Ptr, peek) import Foreign.Marshal.Alloc (alloca) import Foreign.Marshal.Array (peekArray) data HklFactory foreign import ccall safe "hkl.h hkl_factory_get_all" c_hkl_factory_get_all :: Ptr Int -> IO (Ptr HklFactory) hklFactoryGetAll :: IO [HklFactory] hklFactoryGetAll = alloca $ \n -> do factories <- c_hkl_factory_get_all n peekArray n factories but indeed it doesn not work, peekArray complain that n is Ptr Int instead of Int. what should I do in order to get my array of HklFactory thanks for your help. Frederic

Hi, you have to peek the pointed value. Something like: hklFactoryGetAll :: IO [HklFactory] hklFactoryGetAll = alloca $ \ptrn -> do factories <- c_hkl_factory_get_all ptrn n <- peek ptrn peekArray n factories 2015-11-08 10:55 GMT+01:00 PICCA Frederic-Emmanuel < frederic-emmanuel.picca@synchrotron-soleil.fr>:
Hello,
Here the signature of one of my C function
-- hkl.h --
typedef struct _HklFactory HklFactory;
HKLAPI HklFactory **hkl_factory_get_all(size_t *n) HKL_ARG_NONNULL(1);
HKLAPI HklFactory *hkl_factory_get_by_name(const char *name, GError **error) HKL_ARG_NONNULL(1) HKL_WARN_UNUSED_RESULT;
HKLAPI const char *hkl_factory_name_get(const HklFactory *self) HKL_ARG_NONNULL(1);
HKLAPI HklGeometry *hkl_factory_create_new_geometry(const HklFactory *self) HKL_ARG_NONNULL(1);
HKLAPI HklEngineList *hkl_factory_create_new_engine_list(const HklFactory *self) HKL_ARG_NONNULL(1);
I will focuss for now only the get_all method. As you can see even for the C client of my API HklFactory is an opac struct This get_all method return an array of (HklFactory *) and get the size of the array via the n parameter.
So I am trying to use this API from haskell with the foreign system and return a [HklFactory]
import Foreign (Ptr, peek) import Foreign.Marshal.Alloc (alloca) import Foreign.Marshal.Array (peekArray)
data HklFactory
foreign import ccall safe "hkl.h hkl_factory_get_all" c_hkl_factory_get_all :: Ptr Int -> IO (Ptr HklFactory)
hklFactoryGetAll :: IO [HklFactory] hklFactoryGetAll = alloca $ \n -> do factories <- c_hkl_factory_get_all n peekArray n factories
but indeed it doesn not work, peekArray complain that n is Ptr Int instead of Int.
what should I do in order to get my array of HklFactory
thanks for your help.
Frederic _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

Ok, so now I get this error ghkl.hs:20:18: No instance for (Foreign.Storable.Storable HklFactory) arising from a use of ‘peekArray’ In a stmt of a 'do' block: peekArray n factories In the expression: do { factories <- c_hkl_factory_get_all ptr; n <- peek ptr; peekArray n factories } In the second argument of ‘($)’, namely ‘\ ptr -> do { factories <- c_hkl_factory_get_all ptr; n <- peek ptr; .... }’ What should I do to create a Storable for HklFactory which is a simple pointer. Thanks Frederic

You can alias HklFactory: type HklFactory = Ptr () Or if you want to avoid mixing HklFactory and other pointers, you can use: newtype HklFactory = HklFactory (Ptr ()) deriving (Storable) The latter requires the GeneralizedNewtypeDeriving extension, see: https://wiki.haskell.org/Foreign_Function_Interface#Renaming_and_Storable_in... Sylvain 2015-11-08 21:30 GMT+01:00 PICCA Frederic-Emmanuel < frederic-emmanuel.picca@synchrotron-soleil.fr>:
Ok, so now I get this error
ghkl.hs:20:18: No instance for (Foreign.Storable.Storable HklFactory) arising from a use of ‘peekArray’ In a stmt of a 'do' block: peekArray n factories In the expression: do { factories <- c_hkl_factory_get_all ptr; n <- peek ptr; peekArray n factories } In the second argument of ‘($)’, namely ‘\ ptr -> do { factories <- c_hkl_factory_get_all ptr; n <- peek ptr; .... }’
What should I do to create a Storable for HklFactory which is a simple pointer.
Thanks
Frederic _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

Thanks a lot it works now :)
________________________________________
De : Beginners [beginners-bounces@haskell.org] de la part de Sylvain Henry [hsyl20@gmail.com]
Envoyé : dimanche 8 novembre 2015 21:45
À : The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell
Objet : Re: [Haskell-beginners] ffi array and peekArray
You can alias HklFactory:
type HklFactory = Ptr ()
Or if you want to avoid mixing HklFactory and other pointers, you can use:
newtype HklFactory = HklFactory (Ptr ()) deriving (Storable)
The latter requires the GeneralizedNewtypeDeriving extension, see: https://wiki.haskell.org/Foreign_Function_Interface#Renaming_and_Storable_in...
Sylvain
2015-11-08 21:30 GMT+01:00 PICCA Frederic-Emmanuel
participants (2)
-
PICCA Frederic-Emmanuel
-
Sylvain Henry