question concerning ANSI "void *"

Hello, Ok .. I am writing a Haskell function that will call down into the ANSI C library .. blah :: .... -> Ptr Word8 ....-> .... The underlying C function that "blah" is calling has a "void *" so I am using "Ptr Word 8" to model the "void *". I propose to have the callers of function "blah" to populate a data structure something like "Ptr Buz" where "data Buz = { ........} and then do a "recast :: Ptr Word 8 -> Ptr Buz" when invoking function "blah". Does this seem reasonable? Is there a better way? Thanks, Vasili

2008/2/7 Galchin Vasili
Ok .. I am writing a Haskell function that will call down into the ANSI C library .. blah :: .... -> Ptr Word8 ....-> .... The underlying C function that "blah" is calling has a "void *" so I am using "Ptr Word 8" to model the "void *".
Depending on the context, "void *" is generally either taken as a Ptr () (for an opaque pointer) or Ptr Word8 (for calls like memcpy).
I propose to have the callers of function "blah" to populate a data structure something like "Ptr Buz" where "data Buz = { ........} and then do a "recast :: Ptr Word 8 -> Ptr Buz" when invoking function "blah". Does this seem reasonable? Is there a better way?
Generally, Ptr x is only used where x is either a shadow type or a Bits type. Having a Ptr Baz where Baz is an ADT seems a little odd. If you need to translate a structure from Haskell to C code, probably you are better off having callers pass in a Baz then, internal to the wrapping, fill out the C structure and call the FFI function with a Ptr CBaz (where CBaz is a shadow type). AGL -- Adam Langley agl@imperialviolet.org http://www.imperialviolet.org 650-283-9641

Let's take a concrete but "made up" case .. suppose we want to call through
to pthread_create and pass the (void *) argument to pthread_create which in
turn gets interpreted by the pthread that is launched. How would one
populate the C struct that is passed to the launched pthread keeping in mind
that this C struct is variable in length? From the FFI how would one model
this C struct?
Thanks, Vasili
On 2/7/08, Adam Langley
2008/2/7 Galchin Vasili
: Ok .. I am writing a Haskell function that will call down into the
ANSI
C library .. blah :: .... -> Ptr Word8 ....-> .... The underlying C function that "blah" is calling has a "void *" so I am using "Ptr Word 8" to model the "void *".
Depending on the context, "void *" is generally either taken as a Ptr () (for an opaque pointer) or Ptr Word8 (for calls like memcpy).
I propose to have the callers of function "blah" to populate a data structure something like "Ptr Buz" where "data Buz = { ........} and then do a "recast :: Ptr Word 8 -> Ptr Buz" when invoking function "blah". Does this seem reasonable? Is there a better way?
Generally, Ptr x is only used where x is either a shadow type or a Bits type. Having a Ptr Baz where Baz is an ADT seems a little odd. If you need to translate a structure from Haskell to C code, probably you are better off having callers pass in a Baz then, internal to the wrapping, fill out the C structure and call the FFI function with a Ptr CBaz (where CBaz is a shadow type).
AGL
-- Adam Langley agl@imperialviolet.org http://www.imperialviolet.org 650-283-9641

On Feb 8, 2008 9:13 AM, Galchin Vasili
Let's take a concrete but "made up" case .. suppose we want to call through to pthread_create and pass the (void *) argument to pthread_create which in turn gets interpreted by the pthread that is launched. How would one populate the C struct that is passed to the launched pthread keeping in mind that this C struct is variable in length? From the FFI how would one model this C struct?
It tough to be helpful with such a generic request. Here are some options that you can consider: 1) Write a wrapper function in C which has a nicer FFI interface to call from Haskell. Using cabal this is pretty painless and, if the interface suits it, it probably the easiest solution. 2) Call pthread_create directly with the FFI. You can give the FFI function a Haskell type with 'Ptr ()' or 'Ptr X', it doesn't really matter. However the type system serves you best, do it that way. This means that you need to populate the struct yourself in Haskell. The issue with this is that the local system defines lots of things like padding and alignment which mean that the layout of the structure in memory is complex and platform specific. Tools like hsc2hs[1] or c2hs will be very helpful here. Dealing with the variable length probably isn't an issue. Usually variable length structures have a fixed header and a variable tail, where the tail is an array of primitives. You can malloc the correct sized region, use one of the previous tools to fill in the fixed header and then use poke to complete the tail. I might be able to be more helpful if you give the actual struct and function prototype that you're trying to wrap. Cheers [1] http://therning.org/magnus/archives/tag/hsc2hs [2] http://www.cse.unsw.edu.au/~chak/haskell/c2hs/ -- Adam Langley agl@imperialviolet.org http://www.imperialviolet.org 650-283-9641

a couple of concrete examples:
typedef struct {char a; int b; char str[8]} type1;
typedef struct {long c; char d} type2;
So to pthread_create (just an example function) we could be passing a struct
of type1 or a struct of type2 .. i.e. arbitrary length and content ... I am
trying to better understand this. I see some of the poke functions mentioned
in the FFI. Which one are you alluding to?
Regards, Vasili
On 2/8/08, Adam Langley
Let's take a concrete but "made up" case .. suppose we want to call
On Feb 8, 2008 9:13 AM, Galchin Vasili
wrote: through to pthread_create and pass the (void *) argument to pthread_create which in turn gets interpreted by the pthread that is launched. How would one populate the C struct that is passed to the launched pthread keeping in mind that this C struct is variable in length? From the FFI how would one model this C struct?
It tough to be helpful with such a generic request. Here are some options that you can consider:
1) Write a wrapper function in C which has a nicer FFI interface to call from Haskell. Using cabal this is pretty painless and, if the interface suits it, it probably the easiest solution. 2) Call pthread_create directly with the FFI. You can give the FFI function a Haskell type with 'Ptr ()' or 'Ptr X', it doesn't really matter. However the type system serves you best, do it that way. This means that you need to populate the struct yourself in Haskell. The issue with this is that the local system defines lots of things like padding and alignment which mean that the layout of the structure in memory is complex and platform specific. Tools like hsc2hs[1] or c2hs will be very helpful here. Dealing with the variable length probably isn't an issue. Usually variable length structures have a fixed header and a variable tail, where the tail is an array of primitives. You can malloc the correct sized region, use one of the previous tools to fill in the fixed header and then use poke to complete the tail.
I might be able to be more helpful if you give the actual struct and function prototype that you're trying to wrap.
Cheers
[1] http://therning.org/magnus/archives/tag/hsc2hs [2] http://www.cse.unsw.edu.au/~chak/haskell/c2hs/
-- Adam Langley agl@imperialviolet.org http://www.imperialviolet.org 650-283-9641

basically I am trying to implement ioctl for the Posix library .. so a
possible signtaure would be:
fdIoctl :: Fd -> Int -> Ptr Word 8 -> IO( Ptr Word8) ????
Vasili
On 2/8/08, Galchin Vasili
a couple of concrete examples:
typedef struct {char a; int b; char str[8]} type1;
typedef struct {long c; char d} type2;
So to pthread_create (just an example function) we could be passing a struct of type1 or a struct of type2 .. i.e. arbitrary length and content ... I am trying to better understand this. I see some of the poke functions mentioned in the FFI. Which one are you alluding to?
Regards, Vasili
On 2/8/08, Adam Langley
wrote: Let's take a concrete but "made up" case .. suppose we want to call
On Feb 8, 2008 9:13 AM, Galchin Vasili
wrote: through to pthread_create and pass the (void *) argument to pthread_create which in turn gets interpreted by the pthread that is launched. How would one populate the C struct that is passed to the launched pthread keeping in mind that this C struct is variable in length? From the FFI how would one model this C struct?
It tough to be helpful with such a generic request. Here are some options that you can consider:
1) Write a wrapper function in C which has a nicer FFI interface to call from Haskell. Using cabal this is pretty painless and, if the interface suits it, it probably the easiest solution. 2) Call pthread_create directly with the FFI. You can give the FFI function a Haskell type with 'Ptr ()' or 'Ptr X', it doesn't really matter. However the type system serves you best, do it that way. This means that you need to populate the struct yourself in Haskell. The issue with this is that the local system defines lots of things like padding and alignment which mean that the layout of the structure in memory is complex and platform specific. Tools like hsc2hs[1] or c2hs will be very helpful here. Dealing with the variable length probably isn't an issue. Usually variable length structures have a fixed header and a variable tail, where the tail is an array of primitives. You can malloc the correct sized region, use one of the previous tools to fill in the fixed header and then use poke to complete the tail.
I might be able to be more helpful if you give the actual struct and function prototype that you're trying to wrap.
Cheers
[1] http://therning.org/magnus/archives/tag/hsc2hs [2] http://www.cse.unsw.edu.au/~chak/haskell/c2hs/
-- Adam Langley agl@imperialviolet.org http://www.imperialviolet.org 650-283-9641

On Feb 8, 2008 10:57 AM, Galchin Vasili
basically I am trying to implement ioctl for the Posix library .. so a possible signtaure would be:
fdIoctl :: Fd -> Int -> Ptr Word 8 -> IO( Ptr Word8) ????
Ah, ok. You could cover many of the ioctls (the ones which only take a single primitive) by using the Storable class and the types CInt etc. Define the FFI call to ioctl with a type of CInt -> Int -> Ptr () -> IO CInt and then ioctlCInt :: CInt -> CInt -> CInt -> IO CInt ioctlCInt fd call arg = do allocaBytes $ \ptr -> do poke ptr arg result <- ioctl fd call (cast ptr) when (result < 0) $ fail "ioctl error" peek ptr (untested, might work ;) ... and likewise for the other C types. However, for those ioctls which take a complex structure (e.g. many of the networking ones), you'll need to marshal yourself: data SomeIOCtlStruct = CInt CInt CInt ioctlSomeIOCtlStruct :: CInt -> CInt -> SomeIOCtlStruct -> IO () ioctlSomeIOCtlStruct = do ... (see the above linked to pointers to hsc2hs and c2hs about how to write this function) AGL -- Adam Langley agl@imperialviolet.org http://www.imperialviolet.org 650-283-9641

Galchin Vasili wrote:
Let's take a concrete but "made up" case .. suppose we want to call through to pthread_create and pass the (void *) argument to pthread_create which in turn gets interpreted by the pthread that is launched. How would one populate the C struct that is passed to the launched pthread keeping in mind that this C struct is variable in length? From the FFI how would one model this C struct?
In this case I'd use Storable a => Ptr a and provide an instance Storable for the actual type you want to marshal. You can allocate the struct with Foreign.Marshal.Alloc.malloc and marshall it from Haskell to C with Foreign.Storable.poke. Cheers Ben
participants (3)
-
Adam Langley
-
Ben Franksen
-
Galchin Vasili