Considering that the GHC FFI is already built on libffi (I'm reasonably sure) it seems unnecessary for the Hackage library to depend on an external version. Is it not already getting linked in?


On Sun, Feb 17, 2013 at 6:53 PM, Ryan Newton <rrnewton@gmail.com> wrote:
> The scenario is pretty simple.  I generate C code at runtime.  I compile it
> to a .so.  I know how many arguments it expects (but only at runtime), and
> I get a FunPtr back from 'dlsym'.  How do I call it?
I feel that I might be confused about the problem, but since I don't
see anyone direct answers -- in order to call a FunPtr, you can use
foreign import ccall "dynamic", to create a regular function.   As
described in the library documentation for Foreign.Ptr, which I bet
you've seen, so you know this.
You can cast the FunPtr to whatever type you like, so you can call the
function with an argument list different from its initial declaration.

My problem is that I can't create a type representing what I want at the Haskell type-check time, and I need such a type for either casting or a foreign import.  For example, let's say the function takes a number of Int arguments between 1 and 1000.  If I find out at runtime that I need a function with 613 Int arguments, I would need to create the type (Int -> Int ... -> IO ()) to cast to.  I suppose there may be some way to create such a dependent type with Typeable/Data.Dynamic, since it's monomorphic.  Or in theory you could dynamically generate new Haskell code to create the type (System.Eval.Haskell)...

libffi, which Krzysztof mentioned, is a good solution:


Because it allows you to pass a list of arguments

 callFFI :: FunPtr a -> RetType b -> [Arg] -> IO b

But it does introduce an extra dependency on a C library (read, deployment liability).  It "cabal install'd" the first time on my linux box, but my mac said "The pkg-config package libffi is required but it could not be found."  (even though libffi.dylib is definitely installed globally).

Anyway, in this case it wasn't too painful to just generate a bunch of extra boilerplate C functions for (1) creating a data structure to hold the arguments, (2) loading them in one at a time, and (3) deallocating the structure when the call is done.  Yuck.  But no extra dependencies.

Cheers,
  -Ryan


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe