* Types abstraits et Inferface C
@ 1998-10-23 9:27 SURLOG
1998-10-26 20:27 ` Xavier Leroy
0 siblings, 1 reply; 2+ messages in thread
From: SURLOG @ 1998-10-23 9:27 UTC (permalink / raw)
To: Caml List
Bonjour,
Peut-on remonter des types abstraits de données C dans un programme Caml
via l'interface C<->Caml. J'essaye de remonter la librairie ODBC en Caml
mais suis confronte a des types abstraits dans l'interface ODBC.
Merci.
--
Servantec-Surlog
Velizy Plus, Bat. E
1 bis, Rue du Petit Clamart
78140 VELIZY-VILLACOUBLAY
Tel: 01-40-83-00-00 Fax: 01-40-83-18-17
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: Types abstraits et Inferface C
1998-10-23 9:27 Types abstraits et Inferface C SURLOG
@ 1998-10-26 20:27 ` Xavier Leroy
0 siblings, 0 replies; 2+ messages in thread
From: Xavier Leroy @ 1998-10-26 20:27 UTC (permalink / raw)
To: surlog, Caml List
> 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
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~1998-10-27 19:02 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-10-23 9:27 Types abstraits et Inferface C SURLOG
1998-10-26 20:27 ` Xavier Leroy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox