I've written a few FFI bindings that I use for my games:
cute-c2-hsandcute-sound-hs- These are bindings to single-header C libraries. The header itself is included in the git repo.sdl-gpu-hs- This C/C++ library is not included in the repo. It is declared as a dependency viapkgconfig-dependsin the.cabalfile.
Some general tips I've picked up:
hsc2hsworks great. It doesn't do much for you, but it give you a nice way to create safe bindings.- Try to make your binding as "literal" as possible. You will end up with a lot of boilerplate, but it' a good starting point.
- You can embed any C function in Haskell with basically 0 overhead by using raw
Ptrs and primitives. - After you have the verbatim C binding, you can build higher-level bindings. I like to make "simple" bindings next - they hide the
Ptrallocation andpoke-ing with a littleunsafePerformIOand nothing more. - NOTE: If the library passes or returns structs by value, it isn't FFI-compatible. You'll have to write an adapter in C that takes a pointer and dereferences it to pass it by value. I usually have a
c-bitsdirectory for these adapters. The libraries above have examples.
- You can embed any C function in Haskell with basically 0 overhead by using raw
- Does
bgfxhave a proper C API? Or is it C++ only? If it's C++ only, you'll have to write a C wrapper that interops with it. And then you write Haskell bindings to that C wrapper. - In general, you're going to have to learn some C/C++ (and their build systems/compilation model). Or rather, expect to pick some stuff up along the way.
- You'll also need to grok the C library as a C library before you use it in Haskell. I even wrote some C examples to help me learn.
- I definitely recommend Nix if you're going to use C, but if you aren't interested in it, you'll have to figure out how to handle native dependencies for your computer.
- Nix i a great C/C++ package manager, and it will auto-discover dependencies declared in
.cabalfiles (such aspkgconfig-depends).nixpkgs's Haskell build infrastructure works great.- I personally use
haskell.nixbecause I cross-compile from NixOS to Windows. It handles Haskell x-compilation well. For C/C++, you will often have to do a little elbow grease to make it packaged for cross-compilation properly. I've spent a lot of time debugging C cross-compilation. But once it works, it's great!
- Nix i a great C/C++ package manager, and it will auto-discover dependencies declared in
I actually had bgfx in my notes as a library to consider trying out and binding, so it's cool that you're interested in trying it. If you do go after it, feel free to ask for help! I love working on this sort of stuff :)