I want to call a Haskell function from C ++ with the image as a parameter. It's just an unsigned char array with width and height information in pixels.
I still have this working code.
-- Stuff.hs module Stuff where import Data.List import Data.Word import qualified Data.Vector.Unboxed as V import Foreign.Ptr import Foreign.Storable import Foreign.C.Types import Foreign.C.String import Foreign.Marshal.Array import Foreign.Marshal.Alloc foreign export ccall freeResult :: CString -> IO () foreign export ccall doWithImageStruct :: ImageStruct -> IO CString data Image = Image Word32 Word32 (V.Vector Double) type ImageStruct = Ptr ImageStructType -- CUInt is Word32. -- https://hackage.haskell.org/package/base-4.6.0.0/docs/Foreign-C-Types.html
and
// StartEnd.c #include <Rts.h> void HsStart() { int argc = 1; char* argv[] = {"ghcDll", NULL}; // argv must end with NULL // Initialize Haskell runtime char** args = argv; hs_init(&argc, &args); } void HsEnd() { hs_exit(); }
It compiles with
ghc -Wall -O2 -outputdir build -shared -o build\Stuff.dll Stuff.hs StartEnd.c
The cpp part (MSVC 2010) is as follows:
// main.cpp // link with /OPT:NOREF
The output will be as expected:
320 240 768003.0
My question is: is this the right way to do this? Or is it just luck that it is not crashing right now, and in fact I have undefined behavior?
Edit: I fixed the code above to show the correct use of integers of a fixed bit length for future readers of this stream.
c ++ arrays pointers haskell ffi
Tobias Hermann
source share