On Fri, Mar 14, 2014 at 2:00 PM, Yuras Shumovich <shumovi...@gmail.com>wrote:
> 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 <shumovi...@gmail.com > >wrote: > > > > > > > > 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 > > > > > >
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://www.haskell.org/mailman/listinfo/ghc-devs