Bibliothèques externes et FFI
seed interagit avec les bibliothèques de plateforme via des déclarations extern explicites et des entrées de l'éditeur de liens. Les appels étrangers ne sont pas sécurisés jusqu'à ce qu'un wrapper seed audité établisse leur type, leur propriété, leur durée de vie, leurs erreurs et leurs contrats de synchronisation.
Déclarations étrangères
La syntaxe propre est la suivante :
extern "c" fn c_sqrt(value: f64) -> f64 link_name "sqrt";
pub fn sqrt_value(value: f64) -> f64 {
unsafe { c_sqrt(value) }
}
La chaîne facultative après extern sélectionne la convention d'appel. link_name sélectionne le symbole étranger lorsqu'il diffère du seed nom de la déclaration. Les déclarations peuvent se terminer par un point-virgule.
Une déclaration extern n’identifie ni ne charge en elle-même une bibliothèque partagée. Les versions du compilateur direct fournissent explicitement des entrées natives :
seed/compiler/llvm/build/seed \
--emit-binary app \
--link-library /usr/lib/x86_64-linux-gnu/libm.so.6 \
app.sd
Le chemin de la bibliothèque système est spécifique à l'hôte et doit être découvert par la procédure package/install plutôt que codé en dur en tant que valeur portable. --link-library accepte un chemin d'accès à un object/archive partagé ou le nom d'un package seed installé à des niveaux cibles prenant en charge la liaison. --link-object ajoute un fichier objet. Le lanceur de référentiel transmet les indicateurs de compilateur directs pris en charge lorsqu'une application a besoin d'entrées natives explicites.
Exigences du forfait
Un package contenant des déclarations extern doit :
- déclarer
[package].platformsdansseed.toml; - fournir une racine non vide
INSTALL.mddécrivant les packages système, obligatoire ABI versions et configuration non-pkg-config pour chaque plate-forme ; - garder la sélection target/library cohérente avec la matrice cible canonique ;
- transmettez
seed publish --checkavant les workflows de publication ou d’installation.
Exemple de fragment de manifeste :
[package]
name = "math-wrapper"
version = "0.1.0"
kind = "lib"
platforms = ["linux-x86-64", "linux-aarch64"]
La déclaration de la plateforme est des métadonnées de validation et de compatibilité. Il n'installe pas la dépendance du système d'exploitation.
Liste de contrôle pour l'emballage sécurisé
Exposez un coffre-fort ordinaire pub fn uniquement lorsque sa mise en œuvre applique toutes les conditions préalables étrangères pertinentes pour les appelants :
- non-nullité du pointeur, alignement, étendue initialisée et validité de la pointe ;
- longueur et mutabilité du tampon ;
- gérer la propriété et le couplage exact du acquire/release ;
- durée de vie du stockage emprunté pendant l'appel et après toute vue renvoyée ;
- gestion de l'état, du numéro d'erreur et des opérations partielles ;
- durée de vie du rappel, convention d'appel et règles thread/synchronization ;
- compatibilité allocateur-domaine pour les valeurs traversant le ABI;
- disposition spécifique à la cible et ABI hypothèses.
Si le wrapper ne peut pas établir ces conditions, exposez-le sous la forme unsafe fn et documentez les obligations de l'appelant.
Pointeurs et poignées
Les pointeurs bruts utilisent une mutabilité de pointe explicite :
extern "c" fn foreign_open() -> *mut u8;
extern "c" fn foreign_close(handle: *mut u8);
Vérifier une valeur brute ne crée pas une provenance sûre. Préférez un propriétaire nominal audité qui stocke le handle, rejette null pendant la construction, appelle la fonction de libération étrangère à partir de son destructeur et expose uniquement les opérations dont il peut maintenir les conditions préalables.
Ne représentez pas un identifiant étranger comme un entier copiable simplement pour des raisons de commodité. Cela perd le nettoyage exact et permet une publication en double.
Vues étrangères empruntées
Un pointeur étranger ordinaire ou un retour de tranche n'a aucune preuve sûre à vie. @static_view est disponible uniquement sur un extern dont ABI garantit que le str ou la tranche renvoyée a une durée de vie process/static :
@static_view extern "c" fn foreign_version() -> str;
Cet attribut est une assertion de provenance fiable, et non une extension de durée de vie, et l'appel reste dangereux. Les vues étrangères dérivées d'entrées ou de handles doivent être conservées derrière un propriétaire de wrapper plutôt que des vues statiques mal étiquetées.
Ressources à travers seed bibliothèques
Natif seed les bibliothèques utilisent un profil qualifié runtime/allocator identité. Passage string, bytes, shared_bytes, ou des valeurs appartenant au destructeur sur un seed la limite de la bibliothèque est prise en charge uniquement lorsque les artefacts producteur et consommateur ont une cible compatible, ABI, le profil de construction, le profil d'exécution, les fonctionnalités d'exécution et l'identité de l'interface.
Une bibliothèque C arbitraire ne comprend pas ces mises en page possédées. Préférez la structure de mise en page C scalaire et simple, le pointeur et pointer/length ABI aux frontières de tiers, avec conversion et propriété conservées à l'intérieur du seed emballage.
Limites de la cible
L'émission d'objets ne constitue pas une preuve de FFI ou de liaison hébergée. Consultez seed/compiler/llvm/tests/GATE14_TARGET_MATRIX.tsv avant de documenter un package externe comme pris en charge sur une cible. En particulier, la ligne wasm32-wasi actuelle est réservée aux objets et ne fournit pas de FFI ou d'exécution WASI opérationnel.
Grove note de compatibilité
De nombreux wrappers sous le niveau supérieur grove/ l'arborescence utilise une syntaxe étrangère remplacée, des types en majuscules, des assistants d'exécution implicites ou des conventions de propriété manuelle. Leur présence ne constitue pas une preuve qu'ils compilent avec les opérationnels. LLVM langue. Portez et vérifiez un wrapper avant de le répertorier comme bibliothèque externe actuelle.