Search code examples
chaskellbytestring

Passing several ByteStrings to C


I have a C function that I want to expose to Haskell via FFI that takes three strings:

c_fun :: CString -> CString -> CString -> IO ()

How can I use useAsCString from Data.ByteString to pass 3 ByteStrings from Haskell? I.e. I'm looking for a implementation of the following:

haskellFun :: ByteString -> ByteString -> ByteString -> IO ()

useAsCString has type ByteString -> (CString -> IO a) -> IO a, so it's clear how to use it with a function that accepts one CString but I can't figure out how to put it together with three.


Solution

  • Would this work?

    useAsCStrings3
        :: (CString -> CString -> CString -> IO a)
        -> ByteString -> ByteString -> ByteString
        -> IO a
    useAsCStrings3 f a b c =
        useAsCString a (\a' ->
            useAsCString b (\b' ->
                useAsCString c (\c' ->
                    f a' b' c'
                )
            )
        )
    

    It type checks for me, and I've used similar techniques in the past when interoping with a C-library. You could implement your haskellFun as

    haskellFun = useAsCStrings3 c_fun
    

    (note: I swapped the order of arguments to useAsCStrings3 during this edit, otherwise there isn't as pretty of an implementation for haskellFun)