How to bind a window library (in C) to Haskell?
Esa Ilari Vuokko
eivuokko at gmail.com
Sun Feb 26 23:53:54 EST 2006
On 2/27/06, Brian Hulley <brianh at metamilk.com> wrote:
> 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
> 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.
More information about the Glasgow-haskell-users