which typefor this FFI call

Hello I would like to create a binding for this function [1]. herr_t H5Literate( hid_t group_id, H5_index_t index_type, H5_iter_order_t order, hsize_t *idx, H5L_iterate_t op, void *op_data ) My "only" problem is with the op and op_data part. Here the C op signature[2] op -> herr_t (*H5L_iterate_t)( hid_t g_id, const char *name, const H5L_info_t *info, void *op_data) What I would like to do is to create an Haskell function which allows to return what is contained under the op_data. What I understand from this is that I give the H5Literate function an op function which is executed for each group of my hdf5 file. So the op method is called with the releavant parameters. The op_data can be use to accumulate things during the traversal. H5Literate :: Hid -> Index -> Order -> Maybe HSize -> H5Iterate -> _ -> _ type H5Iterate = Hid -> ByteString -> Info -> _ -> _ So it seems to me that I need to use a State inorder to do the accumulation. For exemple,I want to collect each group names and accumulate then in a list. Somy questioniswhat should be the signature of both function. I have also the fealing that the return type MUST have a Storableinstance. Thanks for your help Frederic [1] https://support.hdfgroup.org/HDF5/doc/RM/RM_H5L.html#Link-Iterate [2] https://support.hdfgroup.org/HDF5/doc/RM/RM_H5L.html#Link-Visit

Hi, I would use IORef and StablePtr: import Foreign.StablePtr import Foreign.Ptr import Data.IORef type H5Iterate = Hid -> CString -> Ptr () -> Ptr () -> IO () -- see https://wiki.haskell.org/Foreign_Function_Interface#Function_pointers foreign import ccall "wrapper" mkOp :: H5Iterate -> FunPtr (H5Iterate) foreign import ccall "H5Lvisit" h5iterate :: Hid -> Index -> Order -> FunPtr H5Iterate -> Ptr () -> IO () main = do state <- newIORef [] statePtr <- newStablePtr state let callback :: H5Iterate callback hid name infoptr dataptr = do -- get the state stRef <- deRefStablePtr (castPtrToStablePtr dataptr) st <- readIORef stRef -- compute the new state newSt <- ... -- store the new state writeIORef stRef newSt h5iterate gid idttyp order (mkOp callback) (castStablePtrToPtr statePtr) -- retrieve the final state finalState <- readIORef state - Sylvain On 24/06/2017 15:47, PICCA Frederic-Emmanuel wrote:
Hello
I would like to create a binding for this function [1].
herr_t H5Literate( hid_t group_id, H5_index_t index_type, H5_iter_order_t order, hsize_t *idx, H5L_iterate_t op, void *op_data )
My "only" problem is with the op and op_data part. Here the C op signature[2]
op -> herr_t (*H5L_iterate_t)( hid_t g_id, const char *name, const H5L_info_t *info, void *op_data)
What I would like to do is to create an Haskell function which allows to return what is contained under the op_data. What I understand from this is that I give the H5Literate function an op function which is executed for each group of my hdf5 file. So the op method is called with the releavant parameters. The op_data can be use to accumulate things during the traversal.
H5Literate :: Hid -> Index -> Order -> Maybe HSize -> H5Iterate -> _ -> _
type H5Iterate = Hid -> ByteString -> Info -> _ -> _
So it seems to me that I need to use a State inorder to do the accumulation.
For exemple,I want to collect each group names and accumulate then in a list.
Somy questioniswhat should be the signature of both function.
I have also the fealing that the return type MUST have a Storableinstance.
Thanks for your help
Frederic
[1] https://support.hdfgroup.org/HDF5/doc/RM/RM_H5L.html#Link-Iterate [2] https://support.hdfgroup.org/HDF5/doc/RM/RM_H5L.html#Link-Visit _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

On 26/06/2017 08:18, Sylvain Henry wrote:
Hi,
I would use IORef and StablePtr:
import Foreign.StablePtr import Foreign.Ptr import Data.IORef
type H5Iterate = Hid -> CString -> Ptr () -> Ptr () -> IO ()
-- see https://wiki.haskell.org/Foreign_Function_Interface#Function_pointers foreign import ccall "wrapper" mkOp :: H5Iterate -> FunPtr (H5Iterate)
foreign import ccall "H5Lvisit" h5iterate :: Hid -> Index -> Order -> FunPtr H5Iterate -> Ptr () -> IO ()
main = do state <- newIORef [] statePtr <- newStablePtr state
let callback :: H5Iterate callback hid name infoptr dataptr = do -- get the state stRef <- deRefStablePtr (castPtrToStablePtr dataptr) st <- readIORef stRef -- compute the new state newSt <- ... -- store the new state writeIORef stRef newSt
h5iterate gid idttyp order (mkOp callback) (castStablePtrToPtr statePtr)
Don't forget to: freeStablePtr statePtr
-- retrieve the final state finalState <- readIORef state
- Sylvain
On 24/06/2017 15:47, PICCA Frederic-Emmanuel wrote:
Hello
I would like to create a binding for this function [1].
herr_t H5Literate( hid_t group_id, H5_index_t index_type, H5_iter_order_t order, hsize_t *idx, H5L_iterate_t op, void *op_data )
My "only" problem is with the op and op_data part. Here the C op signature[2]
op -> herr_t (*H5L_iterate_t)( hid_t g_id, const char *name, const H5L_info_t *info, void *op_data)
What I would like to do is to create an Haskell function which allows to return what is contained under the op_data. What I understand from this is that I give the H5Literate function an op function which is executed for each group of my hdf5 file. So the op method is called with the releavant parameters. The op_data can be use to accumulate things during the traversal.
H5Literate :: Hid -> Index -> Order -> Maybe HSize -> H5Iterate -> _ -> _
type H5Iterate = Hid -> ByteString -> Info -> _ -> _
So it seems to me that I need to use a State inorder to do the accumulation.
For exemple,I want to collect each group names and accumulate then in a list.
Somy questioniswhat should be the signature of both function.
I have also the fealing that the return type MUST have a Storableinstance.
Thanks for your help
Frederic
[1] https://support.hdfgroup.org/HDF5/doc/RM/RM_H5L.html#Link-Iterate [2] https://support.hdfgroup.org/HDF5/doc/RM/RM_H5L.html#Link-Visit _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

Hello, I end up with this and it works :) thanks
type H5Iterate a = HId_t -> CString -> In H5L_info_t -> InOut a -> IO HErr_t
foreign import ccall "wrapper" mkOp :: H5Iterate a -> IO (FunPtr (H5Iterate a))
nxEntries ∷ FilePath → IO [String]
nxEntries f = withH5File f $ \h → do
state <- newIORef []
statePtr <- newStablePtr state
let opData = InOut $ castStablePtrToPtr statePtr
let startIndex = Nothing
let indexType = ByName
let order = Native
iop <- mkOp callback
_ <- withInOut_ (maybe 0 hSize startIndex) $ \ioStartIndex ->
h5l_iterate (hid h) (indexTypeCode indexType) (iterOrderCode order) ioStartIndex iop opData
freeHaskellFunPtr iop
freeStablePtr statePtr
-- retrieve the final state
readIORef state
where
callback ∷ H5Iterate a
callback _g n _i (InOut dataptr) =
do
let opData = castWrappedPtr dataptr
-- get the state
stRef <- deRefStablePtr (castPtrToStablePtr opData)
st <- readIORef stRef
-- compute the new state
name <- peekCString n
let newSt = st ++ [name]
print st
print name
print newSt
-- store the new state
writeIORef stRef newSt
return $ HErr_t 0
BUT I lose the type checking at the callback interface.
the ffi call of the h5l_iterate method is
#ccall H5Literate,

On 28/06/2017 15:27, PICCA Frederic-Emmanuel wrote:
my question is, when I write this
let opData = InOut $ castStablePtrToPtr statePtr
I have InOut (Ptr ()) is it possible to have somthing more like InOut (Ptr a) instead ?
Yes it's strange that `castStablePtrToPtr` returns `Ptr ()` instead of `Ptr a`. You can use `castPtr` to get the type back: let opData = InOut $ castPtr $ castStablePtrToPtr statePtr https://www.stackage.org/haddock/lts-8.20/base-4.9.1.0/Foreign-Ptr.html#v:ca... -Sylvain

Yes it's strange that `castStablePtrToPtr` returns `Ptr ()` instead of `Ptr a`. You can use `castPtr` to get the type back:
the type signature of castStablePtrTOPtr is :: StablePtr a -> Ptr () So yes we loose the type. I will check if this work
let opData = InOut $ castPtr $ castStablePtrToPtr statePtr
Thanks Frederic ps: http://hackage.haskell.org/package/base-4.9.1.0/docs/Foreign-StablePtr.html#...
participants (2)
-
PICCA Frederic-Emmanuel
-
Sylvain Henry