From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by yquem.inria.fr (Postfix) with ESMTP id 432BBBC57 for ; Tue, 2 Mar 2010 11:20:21 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AhoDAJd1jEvZSMDdimdsb2JhbACafhUBAQEKCQwHEQUfiBy2BIR7BA X-IronPort-AV: E=Sophos;i="4.49,565,1262559600"; d="scan'208";a="53860493" Received: from fmmailgate01.web.de ([217.72.192.221]) by mail1-smtp-roc.national.inria.fr with ESMTP; 02 Mar 2010 11:20:20 +0100 Received: from smtp07.web.de (fmsmtp07.dlan.cinetic.de [172.20.5.215]) by fmmailgate01.web.de (Postfix) with ESMTP id 6A50014A42CB4; Tue, 2 Mar 2010 11:19:59 +0100 (CET) Received: from [85.216.85.71] (helo=frosties.localdomain) by smtp07.web.de with asmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.110 #314) id 1NmPCp-00032U-00; Tue, 02 Mar 2010 11:19:59 +0100 Received: from mrvn by frosties.localdomain with local (Exim 4.71) (envelope-from ) id 1NmPCo-0003WS-Kc; Tue, 02 Mar 2010 11:19:58 +0100 From: Goswin von Brederlow To: Florent Monnier Cc: caml-list@yquem.inria.fr Subject: Re: [Caml-list] How to pass C pointers to Caml References: <9dfe358d1002281955k4cb9207bi4afe5d649fc20e05@mail.gmail.com> <201003010722.15601.monnier.florent@gmail.com> <87tyt0jhsy.fsf@frosties.localdomain> <201003020004.22232.monnier.florent@gmail.com> Date: Tue, 02 Mar 2010 11:19:58 +0100 In-Reply-To: <201003020004.22232.monnier.florent@gmail.com> (Florent Monnier's message of "Tue, 2 Mar 2010 00:04:22 +0100") Message-ID: <87vddfhvox.fsf@frosties.localdomain> User-Agent: Gnus/5.110009 (No Gnus v0.9) XEmacs/21.4.22 (linux, no MULE) MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit Sender: goswin-v-b@web.de X-Sender: goswin-v-b@web.de X-Provags-ID: V01U2FsdGVkX18PI6XpEwrOWdPQYTjkT1FDYsOBE3E+edjwKbe1 vVJs/c2oEZb871mgWRmmiVsuer8VB0q3evwtFIgUdy+ikLwAVr kC5kkvQRM= X-Spam: no; 0.00; pointers:01 ocaml:01 pointers:01 ocaml:01 pointer:01 pointer:01 trivial:01 allocates:01 bindings:01 struct:01 struct:01 finalizer:01 zhao:98 boom:98 mfg:98 Florent Monnier writes: > Le lundi 1 mars 2010 14:24:45, Goswin von Brederlow a écrit : >> Florent Monnier writes: >> > Le lundi 1 mars 2010 04:55:00, Jianzhou Zhao a écrit : >> >> I have been calling OCaml code from C in my project. >> >> The C code has some pointers to C structures. >> >> I got 'seg fault' when calling the OCaml function receiving >> >> C structure pointers. >> >> >> >> 18.7 at http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html >> >> gives the examples that pass int into OCaml. These examples work for me. >> >> But, Does OCaml support to pass C structure pointers to OCaml? >> > >> > Yes it does. Just cast your pointer to the type value. >> > >> > In this tutorial there is an example "Pointers to C structures": >> > http://www.linux-nantes.org/~fmonnier/OCaml/ocaml-wrapping-c.php#ref_ptr >> > >> > the pointer to a C struct is wrapped on the ocaml side by an abstract >> > type called "t" here, and it is provided back to C with print_t / >> > dump_ptr. >> >> The problem with this trivial approach is that ocaml can store the >> pointer somewhere. When the C pointer is freeed then ocaml has a >> dangling pointer. Worse, if the GC allocates a new heap then the pointer >> might suddenly point into the heap and then BOOM. > > A lot of bindings wrap C pointer, it is known to be a technic that does work. > Dangerous that's true, be if you are very careful, it works. > What you can do is set the pointer to NULL when the struct is freed, and then > each function that uses this struct pointer can first check if the pointer is > NULL or not before to use it, and if it's NULL raise an exception. let x = ref None let called_function c_ptr = x := Some c_ptr How will you get x to be Some NULL? Your C code does not know about the copy. You need to wrap the C pointer into a custom or abstract block first to be able to NULL it. A finalizer in a custom block can also be helpfull here and free the pointer when ocaml no longer needs it. >> It is better to put the pointer into an abstract or custom block. > > You can do this too. Imho you must. Anything else is too dangerous. MfG Goswin