caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Xavier Leroy <Xavier.Leroy@inria.fr>
To: surlog@club-internet.fr, Caml List <caml-list@inria.fr>
Subject: Re: Types abstraits et Inferface C
Date: Mon, 26 Oct 1998 21:27:53 +0100	[thread overview]
Message-ID: <19981026212753.59546@pauillac.inria.fr> (raw)
In-Reply-To: <36304C18.E728D95D@club-internet.fr>; from SURLOG on Fri, Oct 23, 1998 at 11:27:52AM +0200

> Peut-on remonter des types abstraits de données C dans un programme Caml 
> via l'interface C<->Caml.

Oui, il suffit de les faire correspondre à un type abstrait Caml.
Pour être plus concrets, supposons l'interface C suivante:

        typedef ... abstract_ty;
        abstract_ty make(int i);
        int read(abstract_ty a);

En Caml, cela devient:

        type abstract_ty
        external make: int -> abstract_ty = "stub_make"
        external read: abstract_ty -> int = "stub_read"

Dans le "stub code", on a plusieurs possibilités de conversion entre
le type abstract_ty et le type value:

1- Si abstract_ty est un pointeur hors du tas et aligné sur une
frontière de mots (comme le sont tous les pointeurs renvoyés par
malloc()): un cast direct convient.

value stub_make(value i) { return (value) make(Int_val(i)); }
value stub_read(value a) { return Val_int(read((abstract_ty) a)); }

2- Dans les autres cas (abstract_ty pas forcément aligné, ou bien
n'est pas un pointeur mais une struct, ou bien...), le mieux est
d'envelopper les valeurs de type abstract_ty dans des blocs de type
Abstract_tag:

value stub_make(value i) {
  abstract_ty a = make(Int_val(i));
  value res = alloc((sizeof(abstract_ty) + sizeof(value) - 1) / sizeof(value),
                    Abstract_tag);
  *((abstract_ty *) res) = a;
  return res;
}

value stub_read(value a) {
  return Val_int(read(*((abstract_ty *) a)));
}

3- Une variante du cas précédent, utile si une fonction de
déallocation explicite free_ty() est fournie sur le type abstract_ty,
est d'envelopper les abstract_ty dans des objets finalisés, de sorte
que le GC appelle free_ty() lorsque l'objet finalisé devient
inaccessible:

#define Ty_val(v) (*((abstract_ty *) &Field(v, 1)))

static void finalize_ty(value a)
{
  free_ty(&Ty_val(a));
}

value stub_make(value i) {
  abstract_ty a = make(Int_val(i));
  value res =
    alloc_final(1 + (sizeof(abstract_ty) + sizeof(value) - 1) / sizeof(value),
                finalize_ty, 1, 1000);
  Ty_val(res) = a;
  return res;
}

value stub_read(value a) {
  return Val_int(Ty_val(a));
}

Hope this helps,

- Xavier Leroy




      reply	other threads:[~1998-10-27 19:02 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1998-10-23  9:27 SURLOG
1998-10-26 20:27 ` Xavier Leroy [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=19981026212753.59546@pauillac.inria.fr \
    --to=xavier.leroy@inria.fr \
    --cc=caml-list@inria.fr \
    --cc=surlog@club-internet.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).