[Haskell-cafe] FunPtr to C function with #arguments determined atruntime?

Ryan Newton rrnewton at gmail.com
Mon Feb 18 00:53:08 CET 2013


>
> > 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:

    http://www.haskell.org/haskellwiki/Library/libffi

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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20130217/ed71ad29/attachment.htm>


More information about the Haskell-Cafe mailing list