well-typed/hs-bindgen

Generate function pointers from Haskell functions

Opened this issue · 2 comments

If we have a C API with

typedef void (*FunPtr_Void_Int)(int);
callFunPtr(FunPtr_Void_Int);

for which we generate

foreign import capi "example.h callFunPtr"
  cCallFunPtr :: FunPtr_Void_Int -> IO ()

then we might want to be able to pass two categories of functions to cCallFunPtr: other C functions (see #46), or Haskell functions. In other to be able to do the latter, we need to generate

foreign import ccall "wrapper"
  wrapFunPtr_Void_Int :: (Int -> IO ()) -> IO FunPtr_Void_Int

allowing us to write code such as

do
    funPtrFromHaskell <- wrapFunPtr_Void_Int $ \x ->
      putStrLn $ "fromHaskell: " ++ show x
    cCallFunPtr funPtrFromHaskell

Just like resolving function pointers (#49), we should probably analyze the C API to see which which wrappers are required; that is, which of the selected functions take function pointers as argument.

Not directly relevant, but there is some discussion of how these wrappers work at https://stackoverflow.com/questions/57140931/implementation-for-the-wrapper-wrapper-in-haskell-ffi .

For an example use case, consider this definition:

/**
 * \brief Data structure to hold Talise error callback function
 */
typedef struct
{
    uint32_t errSrc;
    const char* (*callbackFunction)(uint32_t errSrc, uint32_t errCode);
} talErrorFunction_t;