Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] Automatic wrapper generator
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Gerd Stolpmann <info@g...>
Subject: Re: [Caml-list] Automatic wrapper generator
On Die, 2004-05-18 at 14:11, Richard Jones wrote:
> The actual problem with Gtk revolves (yet again) around memory
> management.  Gtk uses a rather half-baked reference counting scheme.
> The problems with this are similar to the problems with interfacing
> Perl (see below).
> 
> > However at some stage, the only way to make a genuinely
> > Ocaml centric version of a library such as Gtk is to write
> > the wrapper code by hand.
> > 
> > A low level generator is still useful though.
> > It can help by importing the C interface into Ocaml,
> > so at least you can try to do most of the remodelling
> > to a higher level interface in Ocaml.
> 
> It sounds very similar to Perl4caml, which offers two levels of
> interface.  At the lowest level you get to manipulate SVs, HVs and AVs
> directly from OCaml [1].  You have to convert strings/ints to SVs when
> calling Perl code (using sv_of_string, etc.), and when returning
> values you have to convert them from SVs to OCaml native types (using
> string_of_sv, etc.).  For some libraries I've written high-level
> wrappers which do all this conversion for you, allowing you to use
> objects and modules which look just like OCaml native objects [2].
> 
> Perl uses reference counting.  I still haven't worked out a scheme to
> make reference counting behave well with the OCaml garbage collector,
> so the current version of Perl4caml will never deallocate Perl objects
> (there is an experimental makefile flag to turn deallocation on, but
> this sometimes causes programs to crash).  I've tried wrapping the
> Perl objects in custom blocks, but it doesn't work, and I'd appreciate
> some help sorting it out!

Maybe a look at the WDialog interface for Perl helps:

http://cvs.sourceforge.net/viewcvs.py/wdialog/wdialog/code/src/UI/Stubs/stubs.ml?rev=3.4.2.1&only_with_tag=wdialog-perlapi-030403-branch&view=auto

(Note: This is only in the wdialog-perlapi-030403-branch, and not in the
released version of WDialog.)

This interface exports O'Caml objects as Perl objects, and not the other
way round like Perl4caml. The concept is:

- The objects exist when they exist on the O'Caml side. The Perl 
  object is only a proxy for the O'Caml object.

  The existence is explicitly controlled by the global variable
  uiobjects_list; all existing objects are added to it.

- The O'Caml object has a reference to the Perl proxy, but the Perl
  proxy knows only the ID of the O'Caml object that can be used to
  look it up in uiobjects_list. This is important: In one direction
  one can use addresses to reference, but in the other direction
  one must use a weak name like object IDs.

- There is a finaliser for the O'Caml object. When it is called, the
  reference counter of the Perl proxy is decreased. Usually, the
  counter goes to zero then, and the Perl proxy will be deallocated.
  It may happen, however, that the proxy lives longer than the
  object. However, when one calls methods of such half-dead proxies,
  exceptions are raised, so this is not a problem. A half-dead
  proxy can be detected because the object ID cannot be looked up.

- The remaining question is when an object should be removed from
  uiobject_list. Fortunately, there is a kind of activity cycle, and
  when the cycle is over, it is possible to set uiobject_list:=[].

This solution may be interesting for you, because it demonstrates some
useful techniques like finalisers, and because one can see which
questions must be answered. Btw, the code is fully debugged, and passes
a test showing that all memory is actually freed after the activity
cycle.

I think the point is that this API selects one of the memory managers as
the primary one. For a number of reasons the O'Caml manager was chosen.
In the other language one has only proxies that route accesses across
the language boundary.

A major problem are cyclic references between the managers. When they
cannot be avoided, e.g. to realise callbacks across the language
boundary, the primary manager must record these references explicitly,
and give them a weak name (like the object IDs). It may happen that the
weak name cannot be resolved, and this is handled as a runtime error.
The weak names must be allocated and deallocated explicitly by user code
(Wdialog binds this to the activity cycle, but such a thing is not
available in the general case.)

I hope this gives you some idea how to tackle this problem.

Gerd
-- 
------------------------------------------------------------
Gerd Stolpmann * Viktoriastr. 45 * 64293 Darmstadt * Germany 
gerd@gerd-stolpmann.de          http://www.gerd-stolpmann.de
------------------------------------------------------------

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners