2011/8/12 Thomas Braibant <[email protected]>: > Hi, Hi!
> During my summer vacations, I decided to have fun trying to make an > OCaml binding for a C library (my first time). My requirements were to > have an "OCaml feeling" (i.e. to have an OCaml interface that looks > like the library was written in OCaml), and to have good memory > management (no leaks). > > Following the manual, it was easy to get a working binding for a > subset of the library (enough to follow the tutorial of the given > library). However, I ended up bitten by a nasty problem. > > The OCaml interface looks like this (this is a 2D physic library) : > > module Body : sig > type t (* == body* *) > val make : ... -> t > end > > module Space : sig > type t (* == space* *) > val make : unit -> t > val add_body : t -> Body.t -> unit > val step : t -> unit > end > > On the C side, Space.make and Body.make correspond to functions that > allocates custom blocks that hold space* and body* (the finalizers of > these custom blocks correspond to the relevant free-ing functions in > C). > > However, this is wrong, since with the following piece of code, the GC > has the right to remove the bodies once in the loop (there is no more > reference to them). I end up with a segmentation fault. > > let body1 = Body.make ... in > let body2 = Body.make ... in > let space = Space.make () in > let _ = Space.add_body space body1 in > let _ = Space.add_body space body2 in > for i = 0 to ... do > Space.step space > done;; > > This bodies are not global roots (as far as I understand the > terminology), so I do not see a way to tell the GC not to free the > bodies while there is still a reference to the space they have been > added to. At least, I see no such thing in the documentation. > > The solutions I can imagine are: > - either to define Space.t as a record/tuple that contains a space* > and an OCaml list of the bodies that have been added. This seems a bit > of a duplication of the underlying C library. This is the solution I go for when there is strong necessity for the user to control close/collection by himself, i.e. when the ressource is not a file or something similar.. Otherwise, I use your third option below.. > - either to use some reference counting and memory management as an > interface between the target C library, and the OCaml library. > - either to require the user to use a "free" OCaml function to do the > memory management (this does not meet my requirements, but this is how > my target C library is binded in other functional languages...). Romain -- Caml-list mailing list. Subscription management and archives: https://sympa-roc.inria.fr/wws/info/caml-list Beginner's list: http://groups.yahoo.com/group/ocaml_beginners Bug reports: http://caml.inria.fr/bin/caml-bugs
