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 mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by yquem.inria.fr (Postfix) with ESMTP id 9EFACBC57 for ; Tue, 2 Mar 2010 12:33:44 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AhsDADyGjEvUGyoBi2dsb2JhbACRGYllFQEBAQoLCgcRBR+IHKYnhmctiE+EewQ X-IronPort-AV: E=Sophos;i="4.49,566,1262559600"; d="scan'208";a="58028567" Received: from smtp1-g21.free.fr ([212.27.42.1]) by mail4-smtp-sop.national.inria.fr with ESMTP; 02 Mar 2010 12:33:43 +0100 Received: from smtp1-g21.free.fr (localhost [127.0.0.1]) by smtp1-g21.free.fr (Postfix) with ESMTP id 3EAF394019A; Tue, 2 Mar 2010 12:33:37 +0100 (CET) Received: from localhost.localnet (88-123-244-119.rev.libertysurf.net [88.123.244.119]) by smtp1-g21.free.fr (Postfix) with ESMTP id 4D23394001B; Tue, 2 Mar 2010 12:33:35 +0100 (CET) From: Florent Monnier To: caml-list@yquem.inria.fr, Goswin von Brederlow Subject: Re: [Caml-list] How to pass C pointers to Caml Date: Tue, 2 Mar 2010 12:34:48 +0100 User-Agent: KMail/1.12.2 (Linux/2.6.31.12-desktop586-1mnb; KDE/4.3.2; i686; ; ) References: <9dfe358d1002281955k4cb9207bi4afe5d649fc20e05@mail.gmail.com> <201003020004.22232.monnier.florent@gmail.com> <87vddfhvox.fsf@frosties.localdomain> In-Reply-To: <87vddfhvox.fsf@frosties.localdomain> MIME-Version: 1.0 Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Message-Id: <201003021234.48943.monnier.florent@gmail.com> 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 lib:01 finalizer:01 cheers:01 zhao:98 Le mardi 2 mars 2010 11:19:58, vous avez =E9crit : > Florent Monnier writes: > > Le lundi 1 mars 2010 14:24:45, Goswin von Brederlow a =E9crit : > >> Florent Monnier writes: > >> > Le lundi 1 mars 2010 04:55:00, Jianzhou Zhao a =E9crit : > >> >> 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= _p > >> >tr > >> > > >> > 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 point= er > >> 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. >=20 > let x =3D ref None >=20 > let called_function c_ptr =3D x :=3D Some c_ptr >=20 > How will you get x to be Some NULL? I mean often in a C library pointers to C struct are just pointers to=20 something abstract because a lot of lib C API do hide the struct, and provi= de=20 a function to free the things pointed. So in your wrapper after you call th= e=20 destroy function you can set the pointer to NULL and in the other functions= =20 test if the pointer is NULL before to use it to prevent a user of the wrapp= er=20 to call a function after having called the destroy function. > 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. >=20 > >> It is better to put the pointer into an abstract or custom block. > > > > You can do this too. >=20 > Imho you must. Anything else is too dangerous. Yes it is dangerous, but as I explained with some C libraries this is the o= nly=20 possible solution. If you can do it the other way, then do, while it's inde= ed=20 safer. =2D-=20 Cheers