Biblioteche esterne e FFI
seed interagisce con le librerie della piattaforma tramite dichiarazioni extern esplicite e input del linker. Le chiamate straniere non sono sicure finché un wrapper seed controllato non ne stabilisce il tipo, la proprietà, la durata, l'errore e i contratti di sincronizzazione.
Dichiarazioni straniere
La sintassi pulita è:
extern "c" fn c_sqrt(value: f64) -> f64 link_name "sqrt";
pub fn sqrt_value(value: f64) -> f64 {
unsafe { c_sqrt(value) }
}
La stringa facoltativa dopo extern seleziona la convenzione di chiamata. link_name seleziona il simbolo straniero quando è diverso da seed nome della dichiarazione. Le dichiarazioni possono terminare con un punto e virgola.
Una dichiarazione extern non identifica né carica da sola una libreria condivisa. Le build del compilatore diretto forniscono esplicitamente input nativi:
seed/compiler/llvm/build/seed \
--emit-binary app \
--link-library /usr/lib/x86_64-linux-gnu/libm.so.6 \
app.sd
Il percorso della libreria di sistema è specifico dell'host e deve essere rilevato dalla procedura package/install anziché codificato come valore portabile. --link-library accetta un percorso per un object/archive condiviso o il nome di un pacchetto seed installato a livelli di destinazione che supportano il collegamento. --link-object aggiunge un file oggetto. L'utilità di avvio del repository inoltra i flag del compilatore diretto supportati quando un'applicazione necessita di input nativi espliciti.
Requisiti del pacchetto
Un pacchetto che contiene dichiarazioni extern deve:
- dichiarare
[package].platformsinseed.toml; - fornire una radice non vuota
INSTALL.mdche descriva i pacchetti di sistema, obbligatoria ABI versioni e configurazione non pkg-config per ciascuna piattaforma; - mantenere la selezione target/library coerente con la matrice target canonica;
- passare
seed publish --checkprima dei flussi di lavoro di pubblicazione o installazione.
Frammento manifest di esempio:
[package]
name = "math-wrapper"
version = "0.1.0"
kind = "lib"
platforms = ["linux-x86-64", "linux-aarch64"]
La dichiarazione della piattaforma contiene metadati di convalida e compatibilità. Non installa la dipendenza del sistema operativo.
Lista di controllo del wrapper sicuro
Esporre una normale cassaforte pub fn solo quando la sua implementazione impone ogni precondizione straniera rilevante per i chiamanti:
- non nullità del puntatore, allineamento, estensione inizializzata e validità del puntatore;
- lunghezza del buffer e mutabilità;
- gestire la proprietà ed esatto acquire/release abbinamento;
- durata dello spazio di archiviazione preso in prestito durante la chiamata e dopo ogni visualizzazione restituita;
- gestione dello stato, dell'errore e delle operazioni parziali;
- durata della richiamata, convenzione di chiamata e thread/synchronization regole;
- compatibilità dominio allocatore per valori che attraversano ABI;
- layout specifico per l'obiettivo e ABI ipotesi.
Se il wrapper non è in grado di stabilire queste condizioni, esporlo come unsafe fn e documentare gli obblighi del chiamante.
Puntatori e maniglie
I puntatori grezzi utilizzano la mutabilità esplicita delle punte:
extern "c" fn foreign_open() -> *mut u8;
extern "c" fn foreign_close(handle: *mut u8);
Il controllo di un valore grezzo non crea una provenienza sicura. Preferire un proprietario nominale controllato che memorizzi l'handle, rifiuti null durante la costruzione, chiami la funzione di rilascio esterno dal suo distruttore ed esponga solo le operazioni di cui può mantenere le precondizioni.
Non rappresentare un handle di proprietà straniera come numero intero copiabile solo per comodità. Ciò perde la pulizia esatta e consente il rilascio duplicato.
Viste straniere prese in prestito
Un normale puntatore esterno o un ritorno di slice non ha una prova di durata sicura. @static_view è disponibile solo su an extern di chi ABI garantisce che il restituito str o fetta ha process/static durata:
@static_view extern "c" fn foreign_version() -> str;
Questo attributo è un'asserzione di provenienza attendibile, non un'estensione della durata, e la chiamata rimane non sicura. Le viste esterne derivate dall'input o dall'handle dovrebbero essere mantenute dietro un proprietario del wrapper anziché statiche etichettate erroneamente.
Risorse ovunque seed biblioteche
Nativo seed le biblioteche utilizzano un profilo qualificato runtime/allocator identità. Passando string, bytes, shared_byteso valori di proprietà del distruttore in a seed il confine della libreria è supportato solo quando gli artefatti produttore e consumatore hanno un target compatibile, ABI, profilo di creazione, profilo di runtime, funzionalità di runtime e identità dell'interfaccia.
Una libreria C arbitraria non comprende i layout di proprietà. Preferisci struttura scalare, semplice con layout C, puntatore e pointer/length ABI ai confini di terze parti, con conversione e proprietà mantenute all'interno seed involucro.
Limitazioni del target
L'emissione di oggetti non è una prova di FFI o di collegamento ospitato. Consultare seed/compiler/llvm/tests/GATE14_TARGET_MATRIX.tsv prima di documentare un pacchetto esterno come supportato su una destinazione. In particolare, la riga wasm32-wasi corrente è di soli oggetti e non fornisce un FFI WASI operativo o un runtime.
Grove nota di compatibilità
Molti involucri sotto il livello più alto grove/ tree utilizza sintassi straniera sostituita, tipi in maiuscolo, helper di runtime impliciti o convenzioni di proprietà manuale. La loro presenza non è prova che siano conformi all'operativo LLVM lingua. Porta e verifica un wrapper prima di elencarlo come libreria esterna corrente.