
On Fri, Mar 14, 2014 at 2:00 PM, Yuras Shumovich
On Fri, 2014-03-14 at 09:08 -0400, Edward Kmett wrote:
I spent some time hacking around on this from a library perspective when I had to interoperate with a bunch of Objective C on a 64-bit mac as many of the core library functions you need to FFI out to pass around pairs of Int32s as a struct small enough by the x64 ABI to get shoehorned into one register, and as I was programmatically cloning Objective C APIs via template haskell I couldn't use the usual clunky C shims.
Was it related to language-c-inline package?
It was an exercise in serial yak shaving brought about by writing a realtime GPU-based Metropolis light transport raytracer... er.. nevermind. =)
So if nothing else, you can at least take this as a vote of confidence that
your idea isn't crazy. =)
I'd also be happy to answer questions if you get stuck or need help.
Thank you, Edward
Since there is at least one person how is interested in, I'll start asking questions. Please let me know when I become too noisy :)
For now I'm focused on desugaring phase. Right now
type Fn = CInt -> CInt -> IO () foreign import ccall "wrapper" f :: Fn -> IO (FunPtr Fn)
is desugared into
f :: Fn -> IO (FunPtr Fn) f hsFunc = do sPtr <- newStablePtr hsFunc createAdjustor sPtr staticWrapper ...
Here staticWrapper -- address of C function. It will dereference the sPtr, cast to StgClosure* and call with appropriate arguments. All the arguments are primitive C types (int, char, pointer, etc), so it is easy to convert them to corresponding haskell types via rts_mkInt, rts_mkChar etc.
But I want to allow argument to be C structs.
data CStruct { i :: CInt, j :: CInt } type Fn = CStruct -> IO () foreign import ccall "wrapper" f :: Fn -> IO (FunPtr Fn)
Looks like it is impossible to instantiate CStruct from C function. Is it true? Is it easy to add such functionality?
The only solution I see is to flatten CStruct before creating StablePtr:
f :: Fn -> IO (FunPtr Fn) f hsFunc = do sPtr <- newStablePtr $ \i j -> hsFunc (CStruct i j) createAdjustor sPtr staticWrapper ...
Does it make sense? It will add performance overhead because of additional indirection. Better ideas are welcome.
Not sure. This is a much lower level (and more correct .. and likely faster) approach than I was taking. I'd just built all my functions in a way that would cache the resulting ffi_prep_cif for each signature using typeclass magic. I had to do some allocations on each ffi_call though as well for struct avalues though, so I'm guessing you'd have to do at least that much.
Thanks, Yuras
-Edward
On Fri, Mar 14, 2014 at 7:50 AM, Yuras Shumovich
Hi,
Right now ghc's FFI doesn't support c/c++ structures.
Whenever we have foreign function that accepts or returns struct by value, we have to create wrapper that accepts or returns pointer to struct. It is inconvenient, but actually not a big deal.
But there is no easy workaround when you want to export haskell
function
to use it with c/c++ API that requires structures to be passed by value (Usually it is a callback in c/c++ API. You can't change it's signature, and if it doesn't provide some kind of "void* userdata", then you are stuck.)
I'm interested in fixing that. I'm going to start with 'foreign import "wrapper" ...' stuff.
Calling conventions for passing c/c++ structures by value are pretty tricky and platform/compiler specific. So initially I'll use libffi for that (it will work when USE_LIBFFI_FOR_ADJUSTORS is defined, see rts/Adjustor.c). It will allow me to explore design space without bothering about low level implementation details. Later it could be implemented for native (non-libffi) adjustors.
Is anybody interested it that? I appreciate any comments/ideas.
Right now I don't have clear design. It would be nice to support plain haskell data types that are 1) not recursive, 2) has one constructor and 3) contains only c/c++ types. But it doesn't work with c/c++ unions. Any ideas are welcome.
An example how to use libffi with structures: http://www.atmark-techno.com/~yashi/libffi.html#Structures
Thanks, Yuras
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://www.haskell.org/mailman/listinfo/ghc-devs