2009-06-06 8 views
1

Ich erwäge die Verwendung einer Kombination zwischen OCaml und C-Code in einer neuen Anwendung. Es scheint, dass C-Code aus Ocaml Aufruf ist einfach:Ist es möglich, eine C-Funktion von OCaml aufzurufen, die ein großes Array effizient weiterleitet?

external name : type = C-function-name 

Allerdings scheint es auch, dass in umgekehrt (OCaml von C Aufruf) ist komplizierter:

static void 
    call_ocaml_void (const char * name) 
    { CAMLparam0() ; 
     CAMLlocal1 (ostr) ; 

     ostr = caml_copy_string (name); 

     value * func = caml_named_value ("ocaml_puts") ; 

     if (func == NULL) 
      puts ("caml_named_value failed!") ; 
     else 
      caml_callback (*func, ostr) ; 

     CAMLreturn0 ; 
    } /* call_ocaml_void */ 

(Beispiel aus diesem page)

Und vor allem es beinhaltet kopieren.

Kann mir jemand sagen, ob es möglich ist, den Zugriff auf eine Datenstruktur aus beiden Sprachen zu erlauben? Die Funktionen könnten also nur Zeiger auf die Struktur übergeben, aber beide Sprachen können sie trotzdem lesen.

Ziel ist es, alle Operationen mit OCaml durchzuführen und die Daten dann effizient an die C-Umgebung zu übergeben.

Danke!

Antwort

3

Zunächst können Sie einen beliebigen gespeicherten Wert als abstrakten Typ an ocaml übergeben. Ihr sind severall Problem dabei:

  • Sie nicht einen abstrakten Wert von ocaml ohne externe Funktion in C definiert manipulieren kann
  • Der Garbage Collector sie nicht befreien, und Sie können Speicherverlust (oder zu verwenden einige externe Funktion, um es frei zu befreien, aber Sie verlieren einen Teil der Nützlichkeit von oaml)

Sie können auch benutzerdefinierte Block mit einem Zeiger auf alles verwenden. Dies ist auch ein Bastract-Wert (wie im vorherigen Fall), aber Sie können einen Code hinzufügen, der aufgerufen wird, wenn der benutzerdefinierte Block GCed ist und das das C-Objekt freigibt.

dann für Array von integer/char/float Sie biggaray library „Ein Zeiger p auf eine bereits zugewiesene C oder Fortran Array gewickelt werden kann und zurückgeführt, wie einem großen Array CAML die alloc_bigarray oder alloc_bigarray_dims Funktionen. "siehe the manual

+0

Perfekt. Diese Verbindung ist genau das, was ich brauchte. Vielen Dank! – alvatar

+0

Sie wollen auf jeden Fall Bigarrays. Aber Remi, der Müllsammler wird die abstrakten Typen befreien, warum denken Sie, Sie haben die benutzerdefinierten Operationen struct in C und rufen sie an, um sie beim GC zu registrieren? – nlucaroni

+0

malloc Speicher außerhalb der caml Heap, und caml GC-Ding außerhalb seines Heaps. Wenn also Ihr abstrakter Wert nur ein C-Zeiger auf Speicher ist, wird Caml ihn nicht freigeben. Benutzerdefinierter Block ist GCed, aber kein reiner malloced C-Zeiger. –