Version française
Home     About     Download     Resources     Contact us    
Browse thread
C interface style question
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Olivier Andrieu <oandrieu@n...>
Subject: Re: [Caml-list] On Store_field()
 Thomas Fischbacher [Monday 30 January 2006] :
 >
 > 
 > On Thu, 19 Jan 2006, Damien Doligez wrote:
 > 
 > > >However I strongly recommend instead
 > > >
 > > > StoreField(v,n,(value)(void*)p);
 > > 
 > > This is the only way.  Always use Store_field, Store_double_field,
 > > and Store_double_val.
 > 
 > What you *actually* forgot to tell people is that OCaml
 > unfortunately lacks a macro with which one can store C pointers to
 > alloc_final allocated blocks. If one writes to those using e.g.
 > 
 >   ml_vector = alloc_final(2, finalize_vector, 1, 10);
 >   Store_field(ml_vector, 1,(value)vector);
 > 
 > with vector being a C pointer to a structure, this may or may not
 > lead to random crashes at very unexpected places - because (as I
 > think now) the Store_field macro will be over-eager trying to tell
 > the GC about the value stored - which it should just ignore in this
 > particular case!
 > 
 > Indeed, this has been discussed before, I think:
 > 
 > http://groups.google.de/group/fa.caml/msg/60ace9405fcf60c0?dmode=source&hl=de
 > 
 > So, I would strongly suggest introducing a macro that behaves like this:
 > 
 > #define Store_c_field(block,offset,x) (Field(block,offset)=(value)x)
 > 
 > so that one could then use
 > 
 >   Store_c_field(ml_vector, 1,vector);
 > 
 > I actually just spent a full week tracking down precisely this
 > issue in a not particularly trivial C library interface I am
 > building right now.  After looking in the weirdest places, ensuring
 > it's not an issue with the library wrapped, or the trickier pieces
 > of my own code, I even started patching debugging code into the
 > OCaml bytecode's GC and rebuilding...
 > 
 > So, *please* do the world a great favour and tell people about that
 > issue in the C interface documentation!

Well, it already does:
,----
| Rule 3   Assignments to the fields of structured blocks must be done
| with the Store_field macro (for normal blocks) or Store_double_field
| macro (for arrays and records of floating-point numbers). Other
| assignments must not use Store_field nor Store_double_field. 
`----
Final (aka custom) blocks are not structured blocks but raw blocks
(not traced by the GC), so assignements to those blocks falls in the
"other assignments" category.

A good way to deal with custom blocks in the C code is to create a
small struct type and access the content of the block through this type.

struct custom_foo_bar {
  foo *pointer1;
  bar *pointer3;
};

value alloc_foo_bar (foo *f, bar *b)
{
  value v;
  struct custom_foo_bar *s;
  v = alloc_custom (&foo_bar_ops, sizeof struct custom_foo_bar, 1, 10);
  s = Data_custom_val (v);
  s->p1 = f;
  s->p2 = b;
  return v;
}

-- 
   Olivier