
On 2/27/06, Brian Hulley
1) Does this mean that the FFI can only pass Int, Char etc and not user defined data types or compound data types?
Yes. The idea is that instead of pointers/references you have Ptr a, and instance Storable a that provides marshalling between haskell and C. Very often you actually get two sets of bindings, "raw", exact C-signatures, enums as variables etc, and higher level, implemented on top of the raw-level, where you have data and class declarations to simulate usefull parts of foreign C hierarchy - your code looks more like the higher-level part.
2) I'm also really confused by the different kinds of pointers available, and how to safely store a function closure in some C data structure, and how to use this to call the function from within C and access the result safely
Ptr is basically plain old c-pointer. Haskell, however, just sees it as an address with typetag, and accessing object requires marshalling, typically through Storable-class. FunPtr is basically plain c-function pointer. To create FunPtr's, you need to declare and use ffi-wrappers. Something like (taken from Win32-packages Graphics.Win32.Window): type WindowClosure = HWND -> WindowMessage -> WPARAM -> LPARAM -> IO LRESULT foreign import ccall "wrapper" mkWindowClosure :: WindowClosure -> IO (FunPtr WindowClosure) If you are resource-handling savvy, you need to call freeHaskellFunPtr after you finish using that FunPtr. Of course, plain C-function pointers are naturally FunPtr's, and require no freeing.
3) When does GHC do garbage collection? Is the garbage collection done in the same thread as the executing program? Does GHC run a normal Haskell program using multiple threads? Would I need to link my C DLL with a multithreaded version of the C runtime to avoid problems?
C and ghc memory management are not tied together. You should use your own functions in C to release any memory allocated in C. As far as I understand, haskell gc only happens when you are executing haskell.
Alternatively, has anyone managed to use DirectX or COM from within a Haskell program? (because then I could perhaps rewrite all my gui code from
I have written, but not published, experimental DirectX9.D3D bindings. I plan to publish it at some point, but it's pretty hairy at the moment (and incomplete, not all of D3D is done, also no docs etc). I don't have time to work on them right now, so you might need to put quite an effort in if you wish to use them. (And there is no DirectX 7 bindings, if you are using that for 2D.) Using COM might be pretty obvious if you are willing to play around with IDL and HaskellDirect. (There is no IDL files for DirectX9, so I used various hacks and COM c-interface) Or ofcourse, manually reading COM vtables isn't that hard, either. There are various other things one can do, also. Like using C-interface and thin c-wrapper funcionts (COM interface c-parts are usually preprocessor macros, so linking them in haskell isn't really convient). Or C++. of course, but then
scratch in Haskell...) (I'm loathe to switch to OpenGL because OpenGL is very poorly supported on windows - a default WinXP installation does not come with hardware accelerated OpenGL drivers, afaik, and also I can't find any documentation on the Haskell OpenGL bindings except the Haddock type signatures which are just not nearly enough to understand how to use it, and some out of date docs)
If you are comfortable reading OpenGL spec, the haddock documentation should be pretty simple to follow. HTH, -Esa