From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id p7CAAbQC001449 for ; Fri, 12 Aug 2011 12:10:39 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AusBAFr7RE7RVaG2kGdsb2JhbABBmGmPAwgUAQEBAQkJDQcUBCGBWQITGQEbHgMSEF0BEQEFAVAHo3eCVAqMNoJVhHo7iG0CAwaGQQSTEIxXPINg X-IronPort-AV: E=Sophos;i="4.67,361,1309730400"; d="scan'208";a="115661391" Received: from mail-gx0-f182.google.com ([209.85.161.182]) by mail1-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 12 Aug 2011 12:10:38 +0200 Received: by gxk28 with SMTP id 28so2743306gxk.27 for ; Fri, 12 Aug 2011 03:10:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:from:date:message-id:subject:to:content-type; bh=7H9h8lGYhVn1NHFUtWh+ljwJoZGMJ3gK9r0Skw+K3rI=; b=TyrMiwAFd8I7eX0w5H9zEZnZ30JNZpKwpwITKyo2CRvNsrfsjQ3BYhj2tp39qwxluv u3HRI1bycRUzFgPBraEGPLuhQA/wL/ukSDb9O279XAJvgkFMe1YQlspimK7Wety6IoLD 2ELIIbo15gzaCkCAOH9jxDQq2CBz4iXBkTQbA= Received: by 10.42.115.3 with SMTP id i3mr837104icq.495.1313143837254; Fri, 12 Aug 2011 03:10:37 -0700 (PDT) MIME-Version: 1.0 Received: by 10.42.73.69 with HTTP; Fri, 12 Aug 2011 03:10:17 -0700 (PDT) From: Thomas Braibant Date: Fri, 12 Aug 2011 12:10:17 +0200 Message-ID: To: caml-list@inria.fr Content-Type: text/plain; charset=ISO-8859-1 Subject: [Caml-list] C bindings: memory managment 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. - 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...). Since this problem must be quite frequent (I know of one other instance of it in a C binding), I hope that there are elegant and general solutions. If it is not the case, I would be glad to know of the tricks used by other bindings maintainers With best regards, Thomas Braibant