which typefor this FFI call

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

which typefor this FFI call

PICCA Frederic-Emmanuel
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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: which typefor this FFI call

Sylvain Henry-2
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
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: which typefor this FFI call

Sylvain Henry-2
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
>> [hidden email]
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: which typefor this FFI call

PICCA Frederic-Emmanuel
In reply to this post by Sylvain Henry-2
Thanks a lot Sylvain, I will try this as soon as possible.

Frédéric
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: which typefor this FFI call

PICCA Frederic-Emmanuel
In reply to this post by Sylvain Henry-2
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, <hid_t> -> <H5_index_t> -> <H5_iter_order_t> -> InOut <hsize_t> -> H5L_iterate_t a -> InOut a -> IO <herr_t>


where H5L_iterate_t a = H5Iterate

So the call back should keep the information of the type via a


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 ?

Thanks

Fred
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: which typefor this FFI call

Sylvain Henry-2
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:castPtr

-Sylvain
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: which typefor this FFI call

PICCA Frederic-Emmanuel
> 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#v:castStablePtrToPtr
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Loading...