Haskell - FFI and Pointers

I use FFI to use a function in C that takes a structure and returns the same structure. The links I saw say that I should use pointers to these structures in order to be able to import them into Haskell. For example.

data Bar = Bar { a :: Int, b :: Int }
type BarPtr = Ptr (Bar)

foreign import ccall "static foo.h foo"
    f_foo :: BarPtr -> BarPtr

Now I have a problem that I should be able to use this function. references I saw functions like BarPtr → IO () and used c , which has the signature Storable a => a → (Ptr a → IO b) → IO b , which was normal because they called the function inside main.

However, I would like to wrap this function in the library, getting a function like Bar → Bar without I / O, can I do without unsafePerformIO ? What is the procedure?

+4
source share
1 answer

Cannot be removed IOfrom type without use unsafePerformIO. However, in this case, you can get a function with the type you want, with some caveats. In particular, the C function "foo" cannot depend on any global variables, a thread-local state, or anything other than a single argument. In addition, the call foo(bar)should always provide the same result when it bardoes not change.

I expect an attempt to import a C function

bar foo(bar input);

f_foo :: BarPtr -> BarPtr

- . , ( C):

void wrap_foo(bar *barPtr) {
    bar outp = foo(*barPtr);
    *barPtr = outp;
}

f_wrap_foo :: BarPtr -> IO ()

, :

fooBar :: Bar -> Bar
fooBar bar = unsafePerformIO $ with bar $ \barPtr -> do
    f_wrap_foo barPtr
    peek barPtr
+5

All Articles