Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell FFI: How do you wrap C++ collections?

I have a function that returns vector<MyClass>; what's the best way to change this into something FFI-appropriate?

I'm thinking a type like :: [CIntPointer] might be a nice compromise, if possible to obtain.

like image 851
gatoatigrado Avatar asked Feb 27 '12 00:02

gatoatigrado


1 Answers

You could define your own C functions to alloc, free, insert, remove, etc. These functions can wrap the C++ container you want to access. For example:

extern "C" {

Obj * obj_create()
{
  return new Obj();
}

void obj_destroy(Obj * schema)
{
  delete obj;
  obj = NULL;
}
...
...
}

then declare them in the FFI and wrap them any way you'd like.

data SomeObject

type Obj = Ptr SomeObject

foreign import ccall unsafe "obj_create"
    createObj :: IO Obj

foreign import ccall unsafe "obj_destroy"
    destroyObj_ :: Obj -> IO ()

foreign import ccall unsafe "&obj_destroy"
    destroyObj :: FunPtr (Obj -> IO ())

Some Gotchas:

  1. Make sure you compile the C files with a c++ compiler(g++ instead of gcc). this will ensure that the stdc++ libs get picked up correctly.
  2. Pass the library locations (-L) and libs(-lboost*) to link in when compiling the program/lib on the haskell side
like image 150
Chetan Avatar answered Oct 15 '22 14:10

Chetan