Haskell Data.Vector.Storable.unsafeFromForeignPtr with C struct pointer/array field -
i'm using haskell ffi c library defines number of struct
types containing members pointers double
s, intended treated arrays of double
s:
typedef struct foo { int length; double* values; } foot;
in haskell bindings library have equivalent data type in i'm trying use data.vector.storable.vector double
array:
data foo = foo { length :: int, values :: data.vector.storable.vector double } deriving (show, eq)
in order marshall data between c library , haskell code, of course, have write storable
instances these types. i'm trying work out way of using data.vector.storable.unsafefromforeignptr
create haskell vector
s double*
arrays c library has allocated , populated on heap. i'm hoping doing can avoid copying contents of double*
arrays , have vector
kind of wrapper on array. (side question be: given double*
arrays can 10,000s of double
s, worth pursuing non-copying?)
this have far. i'm using hsc2hs
macros generate storable peek
implementation:
instance storable foo alignment _ = alignment (undefined :: cdouble) sizeof _ = #{size foot} peek ptr = len <- (#peek foot, length) ptr valuesfield <- ((#peek foot, values) ptr) :: io (foreignptr double) let values' = dv.unsafefromforeignptr0 valuesfield len return foo { length = len, values = values' } poke ptr (foo len values') = (#poke foot, length) ptr len dv.unsafewith values' (\ptrvalues -> (#poke foot, values) ptr ptrvalues)
so in peek
i'm trying #peek
values
member foreignptr double
use unsafefromforeignptr
. however, #peek
generates code this:
valuesfield <- (((\ hsc_ptr -> peekbyteoff hsc_ptr 16)) ptr) :: io (foreignptr double)
and gets stuck because there's no storable
instance foreignptr double
. think if tried implement instance foreignptr double
commuting problem of how access address value of struct
member peek
implementation instance.
so in summary, how can access address value (i.e. pointer) struct
member in such way can use argument unsafefromforeignptr
?
i don't know using hsc2hs have pointer data in peek
use that, proper offset of course. disclaimer: compiles, untested.
import data.vector.storable (vector, unsafefromforeignptr) import foreign.storable (storable (..)) import foreign.c.types import foreign.foreignptr (newforeignptr_) import foreign.ptr instance storable foo peek ptr = len <- peek (castptr ptr) valsptr <- newforeignptr_ (castptr ptr `plusptr` (sizeof (undefined :: cint))) return $ foo len $ unsafefromforeignptr valsptr 0 len
Comments
Post a Comment