Foreign function interface

Una FFI ( Foreign Function Interface ) è un meccanismo mediante il quale un programma scritto in un linguaggio di programmazione può chiamare routine o fare uso di servizi scritti in un altro.

Etimologia del termine

[modifica | modifica wikitesto]

Il termine deriva dalla specifica di Common Lisp, che fa esplicitamente riferimento alle funzionalità linguistiche per le chiamate tra lingue in quanto tali; il termine è usato anche ufficialmente dai linguaggi di programmazione Haskell e Python. Altre lingue usano un'altra terminologia: il linguaggio di programmazione Ada parla di " binding di linguaggio ", mentre Java fa riferimento al suo FFI come JNI ( Java Native Interface ) o JNA ( Java Native Access ). L'interfaccia per le funzioni estranee è diventata una terminologia generica per i meccanismi che forniscono tali servizi.

La funzione primaria di un'interfaccia di funzione straniera è quella di accoppiare la semantica e chiamare convenzioni di un linguaggio di programmazione (la lingua ospite o la lingua che definisce la FFI), con la semantica e le convenzioni di un'altra (la lingua ospite ). Questo processo deve anche prendere in considerazione gli ambienti di runtime e/o le interfacce binarie delle applicazioni di entrambi. Questo può essere fatto in diversi modi:

  • Richiedere che le funzioni in lingua ospite che devono essere chiamate in linguaggio host siano specificate o implementate in un modo particolare; spesso usando una libreria di compatibilità di qualche tipo.
  • Utilizzo di uno strumento per "avvolgere" automaticamente le funzioni del linguaggio ospite con il codice della colla appropriato, che esegue qualsiasi traduzione necessaria.
  • Uso di librerie di wrapper
  • Limitazione del set di funzionalità della lingua host che possono essere utilizzate in più lingue. Ad esempio, le funzioni C ++ chiamate da C potrebbero non (in generale) includere parametri di riferimento o generare eccezioni.

Le FFI possono essere complicate dalle seguenti considerazioni:

  • Se una lingua supporta la garbage collection (GC) e l'altra no; bisogna fare attenzione che il codice lingua non GC non fa in modo che GC nell'altro fallisca. In JNI, ad esempio, il codice C che "tiene su" i riferimenti oggetto ricevuti da Java deve "registrare" questo fatto con Java runtime environment (JRE); altrimenti, Java può cancellare oggetti prima che C abbia finito con loro. (Il codice C deve anche rilasciare esplicitamente il suo link a qualsiasi oggetto di questo tipo, non appena non vi è più bisogno, di C, di quell'oggetto.)
  • Oggetti complicati o non banali o tipi di dati possono essere difficili da mappare da un ambiente all'altro.
  • Potrebbe non essere possibile per entrambe le lingue mantenere i riferimenti alla stessa istanza di un oggetto mutabile, a causa del problema di mappatura sopra riportato.
  • Una o entrambe le lingue potrebbero essere in esecuzione su una macchina virtuale (VM); inoltre, se entrambe lo sono, queste saranno probabilmente VM diverse.
  • L'ereditarietà cross-language e altre differenze, come tra sistemi di tipi o tra modelli di composizione di oggetti, possono essere particolarmente difficili.

Casi speciali

[modifica | modifica wikitesto]

Ci sono alcuni casi speciali in cui le lingue vengono compilate nella stessa VM bytecode, come Clojure e Java, oltre a Elixir ed Erlang . Poiché non esiste un'interfaccia, non è un FFI, in senso stretto, mentre offre la stessa funzionalità all'utente.

Voci correlate

[modifica | modifica wikitesto]