GoGPT Best VPN GoSearch

Icône de favori OnWorks

perlxs - En ligne dans le Cloud

Exécutez perlxs dans le fournisseur d'hébergement gratuit OnWorks sur Ubuntu Online, Fedora Online, l'émulateur en ligne Windows ou l'émulateur en ligne MAC OS

Il s'agit de la commande perlxs qui peut être exécutée dans le fournisseur d'hébergement gratuit OnWorks en utilisant l'un de nos nombreux postes de travail en ligne gratuits tels que Ubuntu Online, Fedora Online, l'émulateur en ligne Windows ou l'émulateur en ligne MAC OS

PROGRAMME:

Nom


perlxs - Manuel de référence du langage XS

DESCRIPTION


Introduction
XS est un format de fichier de description d'interface utilisé pour créer une interface d'extension entre
Code Perl et C (ou une bibliothèque C) que l'on souhaite utiliser avec Perl. L'interface XS est
combiné avec la bibliothèque pour créer une nouvelle bibliothèque qui peut ensuite être soit dynamiquement
chargée ou liée statiquement en Perl. La description de l'interface XS est écrite dans le fichier XS.
langage et est le composant principal de l'interface d'extension Perl.

Avant d'écrire XS, lisez la section « AVERTISSEMENTS » ci-dessous.

An XSUB constitue l'unité de base de l'interface XS. Après compilation par le xsubpp
compilateur, chaque XSUB équivaut à une définition de fonction C qui fournira le lien entre
Conventions d'appel Perl et conventions d'appel C.

Le code de collage extrait les arguments de la pile Perl, convertit ces valeurs Perl en
formats attendus par une fonction C, appeler cette fonction C, transférer les valeurs de retour de la
Fonction C de retour vers Perl. Les valeurs de retour peuvent être une valeur de retour C conventionnelle ou toute autre valeur C.
Arguments de fonction pouvant servir de paramètres de sortie. Ces valeurs de retour peuvent être transmises.
revenir à Perl soit en les mettant sur la pile Perl, soit en modifiant les arguments
fourni du côté Perl.

Ce qui précède est une vue quelque peu simplifiée de ce qui se passe réellement. Puisque Perl permet plus
conventions d'appel plus flexibles que C, les XSUB peuvent faire beaucoup plus en pratique, comme vérifier
paramètres d'entrée pour la validité, en lançant des exceptions (ou en renvoyant une liste indéfinie/vide) si le
la valeur de retour de la fonction C indique un échec, appelant différentes fonctions C en fonction de
nombres et types d'arguments, fournissant une interface orientée objet, etc.

Bien sûr, on pourrait écrire un tel code de collage directement en C. Cependant, ce serait une tâche fastidieuse.
tâche, surtout si l'on doit écrire de la colle pour plusieurs fonctions C, et/ou si l'on n'est pas
assez familier avec la discipline de la pile Perl et d'autres arcanes similaires. XS arrive au
sauvetage ici : au lieu d'écrire ce code C de colle à la main, on peut écrire un code plus
sténographie concise la description de ce qui doit être fait par la colle, et laissez le compilateur XS
xsubpp gérer le reste.

Le langage XS permet de décrire la correspondance entre la façon dont la routine C est utilisée et
Comment utiliser la routine Perl correspondante. Il permet également de créer des routines Perl.
qui sont directement traduits en code C et qui ne sont pas liés à un code C préexistant
fonction. Dans les cas où l'interface C coïncide avec l'interface Perl, la XSUB
déclaration est presque identique à une déclaration de fonction C (en style K&R). Dans un tel
circonstances, il existe un autre outil appelé « h2xs » qui est capable de traduire un C entier
fichier d'en-tête dans un fichier XS correspondant qui fournira de la colle aux fonctions/macros
décrit dans le fichier d'en-tête.

Le compilateur XS s'appelle xsubppCe compilateur crée les constructions nécessaires pour permettre
un XSUB manipule les valeurs Perl et crée la colle nécessaire pour permettre à Perl d'appeler le XSUB.
Le compilateur utilise cartes de type pour déterminer comment mapper les paramètres de fonction C et les valeurs de sortie
vers les valeurs Perl et inversement. La table de types par défaut (fournie avec Perl) gère de nombreuses valeurs courantes.
Types C. Une table de types supplémentaire peut également être nécessaire pour gérer les structures spéciales et
Types de la bibliothèque liée. Pour plus d'informations sur les table de types, voir perlxstypemap.

Un fichier au format XS commence par une section en langage C qui va jusqu'au premier "MODULE ="
Directive. D'autres directives XS et définitions XSUB peuvent suivre cette ligne. Le « langage »
utilisé dans cette partie du fichier est généralement appelé langage XS. xsubpp
reconnaît et ignore POD (voir perlpod) dans les sections de langage C et XS, ce qui
permet au fichier XS de contenir de la documentation intégrée.

Voir perlxstut pour un tutoriel sur l'ensemble du processus de création d'extension.

Remarque : pour certaines extensions, le système SWIG de Dave Beazley peut fournir une extension nettement plus importante.
Mécanisme pratique pour créer le code de liaison de l'extension. Voirhttp://www.swig.org/> pour
pour en savoir davantage.

On Le manuel de formation Route
La plupart des exemples qui suivent se concentreront sur la création d’une interface entre Perl
et les fonctions de la bibliothèque de liaison ONC+ RPC. rpcb_gettime() la fonction est utilisée pour
illustre de nombreuses fonctionnalités du langage XS. Cette fonction possède deux paramètres : le premier
est un paramètre d'entrée et le second un paramètre de sortie. La fonction renvoie également un
valeur d'état.

bool_t rpcb_gettime(const char *hôte, time_t *timep);

À partir de C, cette fonction sera appelée avec les instructions suivantes.

#inclure
état bool_t ;
temps_t tempsp;
statut = rpcb_gettime( "localhost", &timep );

Si un XSUB est créé pour offrir une traduction directe entre cette fonction et Perl, alors
Ce XSUB sera utilisé depuis Perl avec le code suivant : $status et $timep
les variables contiendront la sortie de la fonction.

utiliser RPC ;
$status = rpcb_gettime( "localhost", $timep );

Le fichier XS suivant montre une sous-routine XS, ou XSUB, qui démontre une possibilité
interface avec le rpcb_gettime() fonction. Ce XSUB représente une traduction directe
entre C et Perl, préservant ainsi l'interface, même depuis Perl. Ce XSUB sera
invoqué depuis Perl avec l'utilisation indiquée ci-dessus. Notez que les trois premiers #include
Les instructions pour « EXTERN.h », « perl.h » et « XSUB.h » seront toujours présentes à la
début d'un fichier XS. Cette approche, ainsi que d'autres, sera développée plus loin dans ce document.
document. Un #define pour « PERL_NO_GET_CONTEXT » doit être présent pour récupérer l'interpréteur.
contexte plus efficacement, voir perlguts pour plus de détails.

#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#inclure

MODULE = RPC PACKAGE = RPC

bool_t
rpcb_gettime(hôte,timep)
char *hôte
temps_t &tempsp
SORTIE:
heure

Toute extension de Perl, y compris celles contenant des XSUB, doit avoir un module Perl pour
servira de module d'amorçage pour intégrer l'extension dans Perl. Ce module exportera le
fonctions et variables de l'extension au programme Perl et entraînera la
XSUB à lier à Perl. Le module suivant sera utilisé pour la plupart des exemples.
dans ce document et doit être utilisé à partir de Perl avec la commande « use » comme indiqué précédemment.
Les modules Perl sont expliqués plus en détail plus loin dans ce document.

paquet RPC;

Exiger l'exportateur ;
nécessite DynaLoader ;
@ISA = qw(Exportateur DynaLoader);
@EXPORT = qw( rpcb_gettime );

RPC d'amorçage ;
1;

Tout au long de ce document, une variété d'interfaces avec le rpcb_gettime() XSUB sera
explorés. Les XSUB prendront leurs paramètres dans des ordres différents ou prendront des
nombre de paramètres. Dans chaque cas, le XSUB est une abstraction entre Perl et le réel
C rpcb_gettime() fonction, et le XSUB doit toujours garantir que le réel rpcb_gettime()
La fonction est appelée avec les paramètres corrects. Cette abstraction permettra
programmeur pour créer une interface plus proche de Perl pour la fonction C.

Le manuel de formation Anatomie of an XSUB
Les XSUB les plus simples se composent de 3 parties : une description de la valeur de retour, le nom de la
Routine XSUB et les noms de ses arguments, ainsi qu'une description des types ou formats de la
arguments.

Le XSUB suivant permet à un programme Perl d'accéder à une fonction de bibliothèque C appelée sans ()L’
XSUB imitera la fonction C qui prend un seul argument et renvoie une seule valeur.

double
péché (x)
double x

En option, on peut fusionner la description des types et la liste des noms d'arguments,
réécrire ceci comme

double
péché(double x)

Cela rend ce XSUB similaire à une déclaration ANSI C. Un point-virgule facultatif est
autorisé après la liste d'arguments, comme dans

double
péché(double x);

Les paramètres avec des types de pointeur C peuvent avoir une sémantique différente : les fonctions C avec des types de pointeur C similaires
déclarations

bool string_ressemble_à_un_nombre(char *s);
bool make_char_uppercase(char *c);

sont utilisées de manière totalement incompatible. Les paramètres de ces fonctions pourraient être
décrit xsubpp comme ça:

char * s
char &c

Ces deux déclarations XS correspondent au type C « char* », mais elles ont des
sémantique, voir « L'opérateur unaire & ».

Il est pratique de penser que l'opérateur d'indirection "*" doit être considéré comme une partie
du type et l'opérateur d'adresse « & » doivent être considérés comme faisant partie de la variable. Voir
perlxstypemap pour plus d'informations sur la gestion des qualificatifs et des opérateurs unaires dans les types C.

Le nom de la fonction et le type de retour doivent être placés sur des lignes séparées et doivent être vidés
ajusté à gauche.

INCORRECT CORRECT

double sin(x) double
double x sin(x)
double x

Le reste de la description de la fonction peut être indenté ou ajusté à gauche.
L'exemple montre une fonction dont le corps est ajusté à gauche. La plupart des exemples de ce document
indenter le corps pour une meilleure lisibilité.

CORRECT

double
péché (x)
double x

Les XSUB plus complexes peuvent contenir de nombreuses autres sections. Chaque section d'un XSUB commence
avec le mot-clé correspondant, tel que INIT: ou CLEANUP:. Cependant, les deux premières lignes
d'un XSUB contiennent toujours les mêmes données : descriptions du type de retour et les noms des
la fonction et ses paramètres. Tout ce qui suit immédiatement est considéré comme
une section INPUT : à moins qu'elle ne soit explicitement marquée par un autre mot-clé. (Voir « La section INPUT :
Mot-clé".)

Une section XSUB continue jusqu'à ce qu'un autre mot-clé de début de section soit trouvé.

Le manuel de formation Argument Stack
La pile d'arguments Perl est utilisée pour stocker les valeurs qui sont envoyées en tant que paramètres au
XSUB et pour stocker ses valeurs de retour. En réalité, toutes les fonctions Perl (y compris
ceux non-XSUB) conservent leurs valeurs sur cette pile en même temps, chacune étant limitée à sa propre
plage de positions sur la pile. Dans ce document, la première position sur cette pile qui
appartient à la fonction active sera appelé position 0 pour cette fonction.

Les XSUB font référence à leurs arguments de pile avec la macro ST(x), Où x fait référence à une position dans
Cette XSUB fait partie de la pile. La position 0 de cette fonction serait connue de la XSUB comme
ST(0). Les paramètres entrants et les valeurs de retour sortantes du XSUB commencent toujours à ST (0).
Pour de nombreux cas simples, le xsubpp le compilateur générera le code nécessaire pour gérer le
pile d'arguments en intégrant des fragments de code trouvés dans les tables de types. Dans les cas plus complexes
le programmeur doit fournir le code.

Le manuel de formation RETOUR Variable
La variable RETVAL est une variable C spéciale qui est déclarée automatiquement pour vous. Le C
Le type de RETVAL correspond au type de retour de la fonction de la bibliothèque C. xsubpp compilateur
déclarera cette variable dans chaque XSUB avec un type de retour autre que « void ». Par défaut,
la fonction C générée utilisera RETVAL pour contenir la valeur de retour de la fonction de la bibliothèque C
appelée. Dans les cas simples, la valeur de RETVAL sera placée dans ST(0) de l'argument
pile où elle peut être reçue par Perl comme valeur de retour du XSUB.

Si le XSUB a un type de retour « void », le compilateur ne déclarera pas de RETVAL
variable pour cette fonction. Lors de l'utilisation d'une section PPCODE : aucune manipulation de RETVAL
une variable est requise, la section peut utiliser la manipulation directe de la pile pour placer les valeurs de sortie
sur la pile.

Si la directive PPCODE : n'est pas utilisée, la valeur de retour « void » doit être utilisée uniquement pour les sous-routines
qui ne renvoient pas de valeur, pair if CODE : la directive utilisée définit ST(0) explicitement.

Les versions antérieures de ce document recommandaient d'utiliser la valeur de retour « void » dans de tels cas.
il a été découvert que cela pouvait conduire à des erreurs de segmentation dans les cas où XSUB était vraiment « vide ». Ceci
Cette pratique est désormais obsolète et pourrait ne plus être prise en charge dans une future version. Utilisez le
renvoie la valeur « SV * » dans de tels cas. (Actuellement, « xsubpp » contient du code heuristique qui
tente de lever l'ambiguïté entre les fonctions « véritablement nulles » et « vieille pratique déclarée comme nulle ».
Par conséquent, votre code est à la merci de cette heuristique, sauf si vous utilisez « SV * » comme valeur de retour.)

Retour SV, AV et HT à travers RETOUR
Lorsque vous utilisez RETVAL pour renvoyer un « SV * », il y a une certaine magie qui se passe derrière le
scènes qui méritent d'être mentionnées. Lorsque vous manipulez la pile d'arguments à l'aide de
Dans la macro ST(x), par exemple, vous devez généralement accorder une attention particulière au nombre de références.
(Pour en savoir plus sur le nombre de références, voir perlguts.) Pour vous simplifier la vie, le typemap
Le fichier rend automatiquement « RETVAL » fatal lorsque vous renvoyez un « SV * ». Ainsi,
les deux XSUB suivants sont plus ou moins équivalents :

annuler
alpha()
CODE PP :
ST(0) = newSVpv("Bonjour le monde",0);
sv_2mortal(ST(0));
XSRETOUR(1);

SV *
bêta()
CODE:
RETVAL = newSVpv("Bonjour le monde",0);
SORTIE:
RETOUR

C'est très utile car cela améliore généralement la lisibilité. Bien que cela fonctionne bien pour un « SV »,
*", il n'est malheureusement pas aussi simple d'avoir "AV *" ou "HV *" comme valeur de retour. Vous devrait
être capable d'écrire :

AV *
array ()
CODE:
RETVAL = newAV();
/* faire quelque chose avec RETVAL */
SORTIE:
RETOUR

Mais en raison d'un bug non réparable (le corriger briserait de nombreux modules CPAN existants) dans le
Dans le fichier typemap, le compteur de références de « AV * » n'est pas correctement décrémenté. Par conséquent,
XSUB ci-dessus présentait une fuite de mémoire à chaque appel. Le même problème se pose pour « HV ».
*", "CV *" et "SVREF" (qui indique une référence scalaire, et non un "SV *" général). Dans XS
code sur perls à partir de perl 5.16, vous pouvez remplacer les mappages de types pour n'importe lequel de ces
types dont la version gère correctement les compteurs de références. Dans la section « TYPEMAP »,

AV* T_AVREF_REFCOUNT_FIXED

pour obtenir la variante réparée. Pour une compatibilité ascendante avec les anciennes versions de Perl,
peut à la place décrémenter le nombre de références manuellement lorsque vous renvoyez l'un des
types susmentionnés utilisant « sv_2mortal » :

AV *
array ()
CODE:
RETVAL = newAV();
sv_2mortal((SV*)RETVAL);
/* faire quelque chose avec RETVAL */
SORTIE:
RETOUR

N'oubliez pas que cette opération n'est pas obligatoire pour un « SV * ». Consultez la documentation de référence pour tous les
les types de base peuvent être trouvés dans perlxstypemap.

Le manuel de formation MODULE Mots-clés
Le mot clé MODULE est utilisé pour démarrer le code XS et pour spécifier le package du
fonctions en cours de définition. Tout le texte précédant le premier mot-clé MODULE est
considéré comme du code C et est transmis à la sortie avec POD dépouillé, mais sinon
intact. Chaque module XS possède une fonction d'amorçage permettant de connecter les XSUB.
en Perl. Le nom du paquet de cette fonction d'amorçage correspondra à la valeur de la dernière
Instruction MODULE dans les fichiers sources XS. La valeur de MODULE doit toujours être conservée.
constante dans le même fichier XS, bien que cela ne soit pas obligatoire.

L'exemple suivant démarrera le code XS et placera toutes les fonctions dans un package
nommé RPC.

MODULE = RPC

Le manuel de formation RANGEMENT Mots-clés
Lorsque les fonctions d'un fichier source XS doivent être séparées en packages, le PACKAGE
Le mot-clé doit être utilisé. Ce mot-clé est utilisé avec le mot-clé MODULE et doit suivre
immédiatement après son utilisation.

MODULE = RPC PACKAGE = RPC

[ Code XS dans le package RPC ]

MODULE = RPC PACKAGE = RPCB

[ Code XS dans le package RPCB ]

MODULE = RPC PACKAGE = RPC

[ Code XS dans le package RPC ]

Le même nom de package peut être utilisé plusieurs fois, ce qui permet d'avoir du code non contigu.
est utile si vous avez un principe de commande plus fort que les noms de packages.

Bien que ce mot-clé soit facultatif et fournisse dans certains cas des informations redondantes, il
doit toujours être utilisé. Ce mot-clé garantit que les XSUB apparaissent dans le format souhaité.
paquet.

Le manuel de formation PRÉFIXE Mots-clés
Le mot-clé PREFIX désigne les préfixes qui doivent être supprimés de la fonction Perl
noms. Si la fonction C est « rpcb_gettime() » et que la valeur du préfixe est « rpcb_ », alors Perl
verra cette fonction comme "gettime()".

Ce mot-clé doit suivre le mot-clé PACKAGE lorsqu'il est utilisé. Si PACKAGE n'est pas utilisé,
PREFIX doit suivre le mot-clé MODULE.

MODULE = PRÉFIXE RPC = rpc_

MODULE = RPC PACKAGE = RPCB PRÉFIXE = rpcb_

Le manuel de formation SORTIE: Mots-clés
Le mot-clé OUTPUT : indique que certains paramètres de fonction doivent être mis à jour (nouveau
valeurs rendues visibles par Perl) lorsque le XSUB se termine ou que certaines valeurs doivent être
renvoyé à la fonction Perl appelante. Pour les fonctions simples sans code : ou
PPCODE : section, telle que sans () fonction ci-dessus, la variable RETVAL est automatiquement
désignée comme valeur de sortie. Pour des fonctions plus complexes, xsubpp le compilateur aura besoin
aider à déterminer quelles variables sont des variables de sortie.

Ce mot-clé sera normalement utilisé en complément du mot-clé CODE : la variable RETVAL
n'est pas reconnue comme variable de sortie lorsque le mot-clé CODE : est présent. La variable OUTPUT :
Le mot-clé est utilisé dans cette situation pour indiquer au compilateur que RETVAL est vraiment une sortie
variable.

Le mot-clé OUTPUT: peut également être utilisé pour indiquer que les paramètres de fonction sont sortis
variables. Cela peut être nécessaire lorsqu'un paramètre a été modifié dans la fonction.
et le programmeur aimerait que la mise à jour soit vue par Perl.

bool_t
rpcb_gettime(hôte,timep)
char *hôte
temps_t &tempsp
SORTIE:
heure

Le mot-clé OUTPUT: permettra également de mapper un paramètre de sortie à une pièce correspondante
de code plutôt que vers une table de types.

bool_t
rpcb_gettime(hôte,timep)
char *hôte
temps_t &tempsp
SORTIE:
timep sv_setnv(ST(1), (double)tempsp);

xsubpp émet un "SvSETMAGIC()" automatique pour tous les paramètres de la section OUTPUT du
XSUB, sauf RETVAL. Il s'agit du comportement généralement souhaité, car il gère correctement
invocation de la magie « set » sur les paramètres de sortie (nécessaire pour les paramètres d'éléments de hachage ou de tableau)
qui doivent être créés s'ils n'existaient pas). Si, pour une raison quelconque, ce comportement n'est pas
souhaité, la section OUTPUT peut contenir une ligne « SETMAGIC: DISABLE » pour la désactiver pour le
le reste des paramètres de la section OUTPUT. De même, « SETMAGIC: ENABLE » peut être
utilisé pour le réactiver pour le reste de la section OUTPUT. Voir perlguts pour plus d'informations.
détails sur la magie « set ».

Le manuel de formation PAS DE SORTIE Mots-clés
Le mot-clé NO_OUTPUT peut être placé comme premier jeton du XSUB. Ce mot-clé indique que
tandis que la sous-routine C à laquelle nous fournissons une interface a un type de retour non « void », le retour
la valeur de cette sous-routine C ne doit pas être renvoyée à partir de la sous-routine Perl générée.

Avec ce mot-clé présent, « La variable RETVAL » est créée, et dans l'appel généré à
la sous-routine à laquelle cette variable est affectée, mais la valeur de cette variable ne va pas
à utiliser dans le code généré automatiquement.

Ce mot-clé n'a de sens que si « RETVAL » doit être accessible par le mot-clé fourni par l'utilisateur
code. Il est particulièrement utile de rendre une interface de fonction plus proche de Perl, en particulier
lorsque la valeur de retour C n'est qu'un indicateur d'erreur. Par exemple,

NO_OUTPUT int
delete_file(char *nom)
APPEL POSTAL :
si (RETVAL != 0)
croak("Erreur %d lors de la suppression du fichier '%s'", RETVAL, name);

Ici, la fonction XS générée ne renvoie rien en cas de succès et mourir() avec
message d'erreur significatif en cas d'erreur.

Le manuel de formation CODE: Mots-clés
Ce mot-clé est utilisé dans les XSUB plus complexes qui nécessitent une gestion spéciale pour le C
fonction. La variable RETVAL est toujours déclarée, mais elle ne sera pas renvoyée à moins qu'elle ne soit
spécifié dans la section OUTPUT :

Le XSUB suivant est destiné à une fonction C qui nécessite une gestion spéciale de ses paramètres.
L'utilisation de Perl est donnée en premier.

$status = rpcb_gettime( "localhost", $timep );

Le XSUB suit.

bool_t
rpcb_gettime(hôte,timep)
char *hôte
temps_t tempsp
CODE:
RETVAL = rpcb_gettime( hôte, &timep );
SORTIE:
heure
RETOUR

Le manuel de formation INIT : Mots-clés
Le mot-clé INIT: permet d'insérer l'initialisation dans le XSUB avant le compilateur
génère l'appel à la fonction C. Contrairement au mot-clé CODE: ci-dessus, ce mot-clé ne
n'affecte pas la façon dont le compilateur gère RETVAL.

bool_t
rpcb_gettime(hôte,timep)
char *hôte
temps_t &tempsp
INIT :
printf("# L'hôte est %s\n", hôte );
SORTIE:
heure

Une autre utilisation de la section INIT: est de vérifier les conditions préalables avant d'effectuer un appel à
la fonction C :

longue longue
lldiv(a,b)
long long un
long long b
INIT :
si (a == 0 && b == 0)
XSRETURN_UNDEF ;
si (b == 0)
croak("lldiv : impossible de diviser par 0");

Le manuel de formation NON_INIT Mots-clés
Le mot-clé NO_INIT est utilisé pour indiquer qu'un paramètre de fonction est utilisé uniquement comme
valeur de sortie. Le xsubpp le compilateur générera normalement du code pour lire les valeurs de tous
paramètres de fonction de la pile d'arguments et les affecter à des variables C lors de l'entrée dans
la fonction. NO_INIT indiquera au compilateur que certains paramètres seront utilisés pour la sortie
plutôt que pour l'entrée et qu'ils seront traités avant la fin de la fonction.

L'exemple suivant montre une variante de la rpcb_gettime() fonction. Cette fonction
utilise la variable timep uniquement comme variable de sortie et ne se soucie pas de sa valeur initiale
Contenu.

bool_t
rpcb_gettime(hôte,timep)
char *hôte
time_t &timep = NO_INIT
SORTIE:
heure

Le manuel de formation CARTE DE TYPES : Mots-clés
À partir de Perl 5.16, vous pouvez intégrer des mappages de types dans votre code XS au lieu de ou dans
Ajout de mappages de types dans un fichier séparé. Plusieurs mappages de types intégrés seront
traités par ordre d'apparition dans le code XS et, comme les fichiers de typemap locaux, prennent
priorité sur la table de types par défaut, les table de types intégrées peuvent écraser les précédentes
Définitions des strophes TYPEMAP, INPUT et OUTPUT. La syntaxe des tableurs de types intégrés est la suivante :

CARTE DE TYPE : <
... votre code typemap ici ...
ICI

où le mot-clé « TYPEMAP » doit apparaître dans la première colonne d'une nouvelle ligne.

Reportez-vous à perlxstypemap pour plus de détails sur l'écriture de cartes de types.

Initialisation Fonction Paramètres
Les paramètres de fonction C sont normalement initialisés avec leurs valeurs à partir de la pile d'arguments
(qui contient à son tour les paramètres qui ont été passés au XSUB depuis Perl). Le
les typemaps contiennent les segments de code qui sont utilisés pour traduire les valeurs Perl en C
paramètres. Le programmeur est toutefois autorisé à remplacer les typesmaps et à fournir
code d'initialisation alternatif (ou supplémentaire). Le code d'initialisation commence par le premier
« = », « ; » ou « + » sur une ligne de la section INPUT : La seule exception se produit si ce « ; »
termine la ligne, puis ce ";" est discrètement ignoré.

Le code suivant montre comment fournir un code d’initialisation pour les paramètres de fonction.
Le code d'initialisation est évalué entre guillemets par le compilateur avant d'être ajouté
à la sortie donc tout ce qui doit être interprété littéralement [principalement "$", "@" ou "\\"]
doivent être protégés par des barres obliques inverses. Les variables $var, $arg et $type peuvent être utilisées comme dans
cartes de types.

bool_t
rpcb_gettime(hôte,timep)
char *host = (char *)SvPV_nolen($arg);
temps_t &timep = 0;
SORTIE:
heure

Ceci ne doit pas être utilisé pour fournir des valeurs par défaut pour les paramètres. On utiliserait normalement
cela lorsqu'un paramètre de fonction doit être traité par une autre fonction de bibliothèque avant de pouvoir
être utilisé. Les paramètres par défaut sont traités dans la section suivante.

Si l'initialisation commence par "=", alors elle est affichée dans la déclaration de l'entrée
variable, remplaçant l'initialisation fournie par la table de types. Si l'initialisation
commence par « ; » ou « + », puis est exécuté une fois que toutes les variables d'entrée ont été
déclaré. Dans le cas « ; », l'initialisation normalement fournie par la table de types n'est pas
effectuée. Dans le cas « + », la déclaration de la variable inclura la
Initialisation à partir de la table de types. Une variable globale, %v, est disponible pour les cas vraiment rares.
cas où les informations d'une initialisation sont nécessaires dans une autre initialisation.

Voici un exemple vraiment obscur :

bool_t
rpcb_gettime(hôte,timep)
time_t ≤ /* \$v{timep}=@{[$v{timep}=$arg]} */
char *host + SvOK($v{timep}) ? SvPV_nolen($arg) : NULL;
SORTIE:
heure

La construction "\$v{timep}=@{[$v{timep}=$arg]}" utilisée dans l'exemple ci-dessus a une double fonction
objectif : premièrement, lorsque cette ligne est traitée par xsubpp, l'extrait Perl "$v{timep}=$arg"
est évalué. Ensuite, le texte de l'extrait évalué est exporté dans le code C généré.
fichier (dans un commentaire C) ! Lors du traitement de la ligne « char *host », $arg évaluera
à ST(0), et $v{timep} sera évalué à ST (1).

Réglage par défaut Paramètre Nos valeurs
Les valeurs par défaut des arguments XSUB peuvent être spécifiées en plaçant une instruction d'affectation dans
la liste des paramètres. La valeur par défaut peut être un nombre, une chaîne ou une chaîne spéciale.
« NO_INIT ». Les valeurs par défaut doivent toujours être utilisées uniquement pour les paramètres les plus à droite.

Pour permettre au XSUB de rpcb_gettime() pour avoir une valeur d'hôte par défaut, les paramètres du
Le XSUB pourrait être réorganisé. Le XSUB appellera alors le vrai rpcb_gettime() fonctionner avec
les paramètres dans le bon ordre. Ce XSUB peut être appelé depuis Perl avec l'une des méthodes suivantes :
déclarations suivantes :

$status = rpcb_gettime( $timep, $host );

$status = rpcb_gettime( $timep );

Le XSUB ressemblera au code suivant. Un bloc CODE: est utilisé pour appeler le
réal rpcb_gettime() fonction avec les paramètres dans l'ordre correct pour cette fonction.

bool_t
rpcb_gettime(timep,host="localhost")
char *hôte
time_t timep = NO_INIT
CODE:
RETVAL = rpcb_gettime( hôte, &timep );
SORTIE:
heure
RETOUR

Le manuel de formation PREINIT : Mots-clés
Le mot-clé PREINIT: permet de déclarer des variables supplémentaires immédiatement avant ou après le
les déclarations des paramètres de la section INPUT: sont émises.

Si une variable est déclarée dans une section CODE: elle suivra tout code de mappage de type qui est
émis pour les paramètres d'entrée. Cela peut entraîner l'apparition de la déclaration après C
code, qui est une erreur de syntaxe C. Des erreurs similaires peuvent se produire avec un type « ; » explicite ou
L'initialisation des paramètres de type « + » est utilisée (voir « Initialisation des paramètres de fonction »).
Déclarer ces variables dans une section INIT: n'aidera pas.

Dans de tels cas, pour forcer une variable supplémentaire à être déclarée avec les déclarations
d'autres variables, placez la déclaration dans une section PREINIT:. Le mot-clé PREINIT:
peut être utilisé une ou plusieurs fois dans un XSUB.

Les exemples suivants sont équivalents, mais si le code utilise des typesmaps complexes, alors le
le premier exemple est plus sûr.

bool_t
rpcb_gettime(timep)
time_t timep = NO_INIT
PREINIT :
char *host = "localhost";
CODE:
RETVAL = rpcb_gettime( hôte, &timep );
SORTIE:
heure
RETOUR

Pour ce cas particulier, un mot-clé INIT: générerait le même code C que PREINIT:
mot-clé. Un autre exemple correct, mais sujet aux erreurs :

bool_t
rpcb_gettime(timep)
time_t timep = NO_INIT
CODE:
char *host = "localhost";
RETVAL = rpcb_gettime( hôte, &timep );
SORTIE:
heure
RETOUR

Une autre façon de déclarer « hôte » est d'utiliser un bloc C dans la section CODE :

bool_t
rpcb_gettime(timep)
time_t timep = NO_INIT
CODE:
{
char *host = "localhost";
RETVAL = rpcb_gettime( hôte, &timep );
}
SORTIE:
heure
RETOUR

La possibilité de placer des déclarations supplémentaires avant que les entrées de typemap ne soient traitées est
très pratique dans les cas où les conversions de typemap manipulent un état global :

MonObjet
muter(o)
PREINIT :
MonÉtat st = global_state;
ENTREE:
MonObjet o;
NETTOYAGE :
réinitialiser_à(état_global, st);

Ici, nous supposons que la conversion vers « MyObject » dans la section INPUT : et depuis MyObject lorsque
Le traitement de RETVAL modifiera la variable globale « global_state ». Après ces conversions,
sont effectuées, nous restaurons l'ancienne valeur de « global_state » (pour éviter les fuites de mémoire, par exemple
exemple).

Il existe une autre façon d'échanger la clarté contre la compacité : les sections INPUT permettent de déclarer
Variables C qui n'apparaissent pas dans la liste des paramètres d'une sous-routine. Ainsi,
code pour subir une mutation() peut être réécrit comme

MonObjet
muter(o)
MonÉtat st = global_state;
MonObjet o;
NETTOYAGE :
réinitialiser_à(état_global, st);

et le code pour rpcb_gettime() peut être réécrit comme

bool_t
rpcb_gettime(timep)
time_t timep = NO_INIT
char *host = "localhost";
C_ARGS :
hôte, &timep
SORTIE:
heure
RETOUR

Le manuel de formation CHAMP D'APPLICATION: Mots-clés
Le mot-clé SCOPE : permet d'activer la portée pour un XSUB particulier. S'il est activé, le
XSUB invoquera automatiquement ENTER et LEAVE.

Pour prendre en charge les mappages de types potentiellement complexes, si une entrée de mappage de types utilisée par un XSUB contient
un commentaire comme "/*scope*/" alors la portée sera automatiquement activée pour ce XSUB.

Pour activer la portée :

PORTÉE : ACTIVER

Pour désactiver la portée :

PORTÉE : DÉSACTIVER

Le manuel de formation ENTREE: Mots-clés
Les paramètres du XSUB sont généralement évalués immédiatement après l'entrée dans le XSUB.
Le mot-clé INPUT : peut être utilisé pour forcer l'évaluation de ces paramètres un peu plus tard.
ENTRÉE : le mot-clé peut être utilisé plusieurs fois dans un XSUB et peut être utilisé pour en répertorier un ou plusieurs.
Plus de variables d'entrée. Ce mot-clé est utilisé avec le mot-clé PREINIT :

L'exemple suivant montre comment le paramètre d'entrée « timep » peut être évalué tardivement, après un
PRÉINIT.

bool_t
rpcb_gettime(hôte,timep)
char *hôte
PREINIT :
temps_t tt;
ENTREE:
temps_t tempsp
CODE:
RETVAL = rpcb_gettime( hôte, &tt );
tempsp = tt;
SORTIE:
heure
RETOUR

L'exemple suivant montre chaque paramètre d'entrée évalué tardivement.

bool_t
rpcb_gettime(hôte,timep)
PREINIT :
temps_t tt;
ENTREE:
char *hôte
PREINIT :
char *h;
ENTREE:
temps_t tempsp
CODE:
h = hôte ;
RETVAL = rpcb_gettime( h, &tt );
tempsp = tt;
SORTIE:
heure
RETOUR

Étant donné que les sections INPUT permettent la déclaration de variables C qui n'apparaissent pas dans le paramètre
liste d'une sous-routine, cela peut être raccourci en :

bool_t
rpcb_gettime(hôte,timep)
temps_t tt;
char *hôte;
char *h = hôte;
temps_t tempsp;
CODE:
RETVAL = rpcb_gettime( h, &tt );
tempsp = tt;
SORTIE:
heure
RETOUR

(Nous avons utilisé nos connaissances selon lesquelles la conversion d'entrée pour « char * » est « simple », donc « hôte »
est initialisé sur la ligne de déclaration, et notre affectation "h = host" n'est pas exécutée non plus
tôt. Sinon, il faudrait avoir l'affectation « h = host » dans un CODE : ou INIT :
section.)

Le manuel de formation ENTRÉE/SORTIE/ENTRÉE_SORTIE/ENTRÉE_SORTIE Mots clés
Dans la liste des paramètres d'un XSUB, on peut précéder les noms de paramètres par le
Mots-clés « IN »/« OUTLIST »/« IN_OUTLIST »/« OUT »/« IN_OUT ». Le mot-clé « IN » est le mot-clé par défaut,
d'autres mots-clés indiquent en quoi l'interface Perl doit différer de l'interface C.

Les paramètres précédés des mots-clés « OUTLIST »/« IN_OUTLIST »/« OUT »/« IN_OUT » sont considérés comme
utilisé par la sous-routine C via PointeursLes mots-clés « OUTLIST »/« OUT » indiquent que le C
la sous-routine n'inspecte pas la mémoire pointée par ce paramètre, mais écrira à travers
ce pointeur pour fournir des valeurs de retour supplémentaires.

Les paramètres précédés du mot-clé « OUTLIST » n'apparaissent pas dans la signature d'utilisation du
fonction Perl générée.

Paramètres précédés de « IN_OUTLIST »/« IN_OUT »/« OUT » do apparaissent comme paramètres du Perl
fonction. À l'exception des paramètres « OUT », ces paramètres sont convertis en
type C correspondant, puis des pointeurs vers ces données sont donnés comme arguments au C
fonction. On s'attend à ce que la fonction C écrive à travers ces pointeurs.

La liste de retour de la fonction Perl générée se compose de la valeur de retour C de la
fonction (sauf si le XSUB est de type de retour « void » ou si « le mot clé NO_OUTPUT » a été utilisé)
suivi de tous les paramètres « OUTLIST » et « IN_OUTLIST » (dans l'ordre d'apparition).
Au retour du XSUB, le paramètre Perl "IN_OUT"/"OUT" sera modifié pour avoir le
valeurs écrites par la fonction C.

Par exemple, un XSUB

annuler
jour_mois(OUTLIST jour, IN unix_time, OUTLIST mois)
jour int
int unix_time
mois int

devrait être utilisé à partir de Perl comme

mon ($jour, $mois) = jour_mois(heure);

La signature C de la fonction correspondante doit être

void jour_mois(int *jour, int unix_time, int *mois);

Les mots-clés « IN »/« OUTLIST »/« IN_OUTLIST »/« IN_OUT »/« OUT » peuvent être mélangés avec le style ANSI
déclarations, comme dans

annuler
jour_mois(OUTLIST int jour, int unix_time, OUTLIST int mois)

(ici le mot-clé facultatif « IN » est omis).

Les paramètres « IN_OUT » sont identiques aux paramètres introduits avec « The & Unary
Opérateur" et placez-le dans la section "OUTPUT :" (voir « Le mot-clé OUTPUT : »).
Les paramètres « IN_OUTLIST » sont très similaires, la seule différence étant que la valeur C
la fonction écrite via le pointeur ne modifierait pas le paramètre Perl, mais est placée dans le
liste de sortie.

Le paramètre « OUTLIST »/« OUT » diffère des paramètres « IN_OUTLIST »/« IN_OUT » uniquement par le
la valeur initiale du paramètre Perl n'est pas lue (et n'est pas donnée à la fonction C)
(qui reçoit des données inutiles à la place). Par exemple, la même fonction C que ci-dessus peut être
interfacé avec comme

void jour_mois(OUT int jour, int unix_time, OUT int mois);

or

annuler
jour_mois(jour, heure_unix, mois)
int &jour = NO_INIT
int unix_time
int &mois = NO_INIT
SORTIE:
journée
mois

Cependant, la fonction Perl générée est appelée dans un style très C :

mon ($jour, $mois);
jour_mois($jour, heure, $mois);

Le manuel de formation "longueur(NOM)" Mots-clés
Si l'un des arguments d'entrée de la fonction C est la longueur d'un argument de chaîne "NAME",
on peut remplacer le nom de l'argument de longueur par "length(NAME)" dans le XSUB
déclaration. Cet argument doit être omis lorsque la fonction Perl générée est appelée.
Par exemple

annuler
dump_chars(char *s, l court)
{
court n = 0;
tant que (n < l) {
printf("s[%d] = \"\\%#03o\"\n", n, (int)s[n]);
n++;
}
}

MODULE = x PACKAGE = x

void dump_chars(char *s, longueur(s) courte(s))

devrait être appelé "dump_chars($string)".

Cette directive est prise en charge uniquement avec les déclarations de fonction de type ANSI.

Longueur variable Paramètre Liste
Les XSUB peuvent avoir des listes de paramètres de longueur variable en spécifiant une ellipse « (...) » dans le
liste de paramètres. Cette utilisation des points de suspension est similaire à celle trouvée dans la norme ANSI C.
le programmeur est capable de déterminer le nombre d'arguments passés au XSUB en examinant
la variable « éléments » que le xsubpp Le compilateur fournit toutes les XSUB. En utilisant ceci
mécanisme permettant de créer un XSUB qui accepte une liste de paramètres de longueur inconnue.

Le manuel de formation hôte paramètre pour la rpcb_gettime() XSUB peut être facultatif, donc les points de suspension peuvent être utilisés
pour indiquer que le XSUB acceptera un nombre variable de paramètres. Perl devrait pouvoir
pour appeler ce XSUB avec l'une des instructions suivantes.

$status = rpcb_gettime( $timep, $host );

$status = rpcb_gettime( $timep );

Le code XS, avec des points de suspension, suit.

bool_t
rpcb_gettime(timep, ...)
time_t timep = NO_INIT
PREINIT :
char *host = "localhost";
CODE:
si( éléments > 1 )
hôte = (char *)SvPV_nolen(ST(1));
RETVAL = rpcb_gettime( hôte, &timep );
SORTIE:
heure
RETOUR

Le manuel de formation C_ARGS : Mots-clés
Le mot-clé C_ARGS: permet de créer des XSUBS qui ont une séquence d'appel différente de
Perl que C, sans avoir besoin d'écrire la section CODE: ou PPCODE:. Le contenu de la
C_ARGS : le paragraphe est placé comme argument de la fonction C appelée sans aucune modification.

Par exemple, supposons qu’une fonction C soit déclarée comme

dérivée symbolique nth(int n, fonction symbolique, int flags);

et que les indicateurs par défaut sont conservés dans une variable C globale « default_flags ». Supposons que
vous souhaitez créer une interface appelée

$second_deriv = $function->n-ième_dérivée(2);

Pour ce faire, déclarez le XSUB comme

symbolique
nth_derivative(fonction, n)
fonction symbolique
entier n
C_ARGS :
n, fonction, indicateurs par défaut

Le manuel de formation CODE PP : Mots-clés
Le mot-clé PPCODE: est une forme alternative du mot-clé CODE: et est utilisé pour indiquer le
xsubpp compilateur auquel le programmeur fournit le code pour contrôler la pile d'arguments
pour les valeurs de retour des XSUB. On souhaitera parfois qu'une XSUB renvoie une liste de
valeurs plutôt qu'une valeur unique. Dans ce cas, il faut utiliser PPCODE : puis
pousser explicitement la liste de valeurs sur la pile. Les mots-clés PPCODE: et CODE: doivent
ne pas être utilisés ensemble dans le même XSUB.

La différence réelle entre les sections PPCODE: et CODE: réside dans l'initialisation de « SP »
macro (qui signifie le actuel pointeur de pile Perl), et dans la gestion des données sur
la pile lors du retour d'une XSUB. Dans les sections CODE : SP préserve la valeur qui a été
à l'entrée du XSUB : SP est sur le pointeur de fonction (qui suit le dernier paramètre).
Dans PPCODE : les sections SP sont déplacées vers l'arrière jusqu'au début de la liste des paramètres, ce qui
permet aux macros "PUSH*()" de placer les valeurs de sortie à l'endroit où Perl s'attend à ce qu'elles soient lorsque
le XSUB revient à Perl.

La bande-annonce générée pour une section CODE : garantit que le nombre de valeurs de retour Perl
verra est soit 0 soit 1 (selon le caractère « vide » de la valeur de retour du C
fonction et heuristiques mentionnées dans « La variable RETVAL »). La bande-annonce générée pour une
PPCODE : la section est basée sur le nombre de valeurs de retour et sur le nombre de fois où « SP »
a été mis à jour par les macros "[X]PUSH*()".

Notez que les macros ST(i), "XST_m*()" et "XSRETURN*()" fonctionnent aussi bien dans les sections CODE :
et PPCODE : sections.

Le XSUB suivant appellera le C rpcb_gettime() fonction et renverra ses deux sorties
valeurs, timep et status, en Perl sous forme de liste unique.

annuler
rpcb_gettime(hôte)
char *hôte
PREINIT :
temps_t tempsp;
état bool_t ;
CODE PP :
statut = rpcb_gettime( hôte, &timep );
ÉTENDRE(SP, 2);
PUSHs(sv_2mortal(newSViv(status)));
PUSHs(sv_2mortal(newSViv(timep)));

Notez que le programmeur doit fournir le code C nécessaire pour avoir le réel
rpcb_gettime() fonction appelée et que les valeurs de retour soient correctement placées sur le
pile d'arguments.

Le type de retour « void » pour cette fonction indique à xsubpp compilateur que le RETVAL
La variable n'est ni nécessaire ni utilisée et ne doit pas être créée. Dans la plupart des cas,
Le type de retour void doit être utilisé avec la directive PPCODE :

Le manuel de formation ÉTENDRE() macro est utilisée pour faire de la place sur la pile d'arguments pour 2 valeurs de retour.
PPCODE : la directive provoque la xsubpp compilateur pour créer un pointeur de pile disponible sous le nom de « SP »,
et c'est ce pointeur qui est utilisé dans le ÉTENDRE() macro. Les valeurs sont alors
poussé sur la pile avec le PUSH() macro.

Maintenant le rpcb_gettime() La fonction peut être utilisée à partir de Perl avec l'instruction suivante.

($status, $timep) = rpcb_gettime("localhost");

Lors de la gestion des paramètres de sortie avec une section PPCODE, assurez-vous de gérer la magie « set »
correctement. Voir perlguts pour plus de détails sur la magie « set ».

Retour Indéfini Et Vide Liste
Parfois, le programmeur voudra simplement renvoyer « undef » ou une liste vide si un
fonction échoue plutôt qu'une valeur d'état distincte. rpcb_gettime() offres de fonctions
Juste cette situation. Si la fonction réussit, nous voudrions qu'elle renvoie l'heure.
et si cela échoue, nous aimerions que la valeur undef soit renvoyée. Dans le code Perl suivant,
la valeur de $timep sera soit indéfinie, soit une heure valide.

$timep = rpcb_gettime( "localhost" );

Le XSUB suivant utilise le type de retour « SV * » comme mnémonique uniquement et utilise un bloc CODE :
pour indiquer au compilateur que le programmeur a fourni tout le code nécessaire.
sv_newmortal() l'appel initialisera la valeur de retour à undef, ce qui en fera la valeur par défaut
valeur de retour.

SV *
rpcb_gettime(hôte)
char * hôte
PREINIT :
temps_t tempsp;
bool_t x;
CODE:
ST(0) = sv_newmortal();
si( rpcb_gettime( hôte, &timep ) )
sv_setnv( ST(0), (double)tempsp);

L'exemple suivant montre comment placer un undef explicite dans la valeur de retour,
si le besoin s'en fait sentir.

SV *
rpcb_gettime(hôte)
char * hôte
PREINIT :
temps_t tempsp;
bool_t x;
CODE:
si( rpcb_gettime( hôte, &timep ) ){
ST(0) = sv_newmortal();
sv_setnv( ST(0), (double)tempsp);
}
sinon {
ST(0) = &PL_sv_undef;
}

Pour renvoyer une liste vide, il faut utiliser un bloc PPCODE: puis ne pas pousser les valeurs de retour dessus
la pile.

annuler
rpcb_gettime(hôte)
char *hôte
PREINIT :
temps_t tempsp;
CODE PP :
si( rpcb_gettime( hôte, &timep ) )
PUSHs(sv_2mortal(newSViv(timep)));
sinon {
/* Rien n'est poussé sur la pile, donc un
* la liste est implicitement renvoyée. */
}

Certaines personnes peuvent être enclines à inclure un « retour » explicite dans le XSUB ci-dessus, plutôt que
Laisser le contrôle jusqu'à la fin. Dans ces situations, « XSRETURN_EMPTY » doit être
utilisé à la place. Cela garantira que la pile XSUB est correctement ajustée. Consultez
perlapi pour les autres macros "XSRETURN".

Étant donné que les macros « XSRETURN_* » peuvent également être utilisées avec des blocs CODE, on peut réécrire ceci
exemple comme :

int
rpcb_gettime(hôte)
char *hôte
PREINIT :
temps_t tempsp;
CODE:
RETVAL = rpcb_gettime( hôte, &timep );
si (RETVAL == 0)
XSRETURN_UNDEF ;
SORTIE:
RETOUR

En fait, on peut également placer ce chèque dans une section « POSTCALL : ». Avec PREINIT :
simplifications, cela conduit à :

int
rpcb_gettime(hôte)
char *hôte
temps_t tempsp;
APPEL POSTAL :
si (RETVAL == 0)
XSRETURN_UNDEF ;

Le manuel de formation EXIGER: Mots-clés
Le mot-clé REQUIRE: est utilisé pour indiquer la version minimale du xsubpp compilateur nécessaire
pour compiler le module XS. Un module XS contenant l'instruction suivante
compiler avec seulement xsubpp version 1.922 ou supérieure :

EXIGE : 1.922

Le manuel de formation NETTOYAGE : Mots-clés
Ce mot-clé peut être utilisé lorsqu'un XSUB nécessite des procédures de nettoyage spéciales avant d'être
se termine. Lorsque le mot-clé CLEANUP : est utilisé, il doit suivre tout CODE : ou OUTPUT :
blocs présents dans le XSUB. Le code spécifié pour le bloc de nettoyage sera
ajouté comme dernières instructions dans le XSUB.

Le manuel de formation APPEL POSTAL : Mots-clés
Ce mot-clé peut être utilisé lorsqu'un XSUB nécessite des procédures spéciales exécutées après le C
L'appel de sous-routine est exécuté. Lorsque le mot-clé POSTCALL: est utilisé, il doit précéder OUTPUT:
et CLEANUP : blocs présents dans le XSUB.

Voir les exemples dans « Le mot clé NO_OUTPUT » et « Retour de listes indéfinies et vides ».

Le bloc POSTCALL: n'a pas beaucoup de sens lorsque l'appel de sous-routine C est fourni par
l'utilisateur en fournissant la section CODE : ou PPCODE :.

Le manuel de formation BATEAU: Mots-clés
Le mot-clé BOOT : est utilisé pour ajouter du code à la fonction d'amorçage de l'extension.
La fonction bootstrap est générée par le xsubpp compilateur et contient normalement les instructions
Il est nécessaire d'enregistrer les XSUB avec Perl. Grâce au mot-clé BOOT:, le programmeur peut savoir
le compilateur pour ajouter des instructions supplémentaires à la fonction d'amorçage.

Ce mot-clé peut être utilisé à tout moment après le premier mot-clé MODULE et doit apparaître sur un
ligne seule. La première ligne vide après le mot-clé terminera le bloc de code.

BATEAU:
# Le message suivant sera imprimé lorsque le
# la fonction bootstrap s'exécute.
printf("Bonjour depuis le bootstrap !\n");

Le manuel de formation VERSIONCHECK : Mots-clés
Le mot-clé VERSIONCHECK: correspond à xsubpp« -versioncheck » et « -noversioncheck »
options. Ce mot-clé remplace les options de ligne de commande. La vérification des versions est activée par
par défaut. Lorsque la vérification de version est activée, le module XS tentera de vérifier que son
la version correspond à la version du module PM.

Pour activer la vérification des versions :

VERSIONCHECK : ACTIVER

Pour désactiver la vérification des versions :

VERSIONCHECK : DÉSACTIVER

Notez que si la version du module PM est un NV (un nombre à virgule flottante), elle sera
stringifié avec une possible perte de précision (actuellement coupé à neuf décimales)
afin qu'il ne corresponde plus à la version du module XS. En citant $VERSION
une déclaration pour en faire une chaîne est recommandée si des numéros de version longs sont utilisés.

Le manuel de formation PROTOTYPES: Mots-clés
Le mot-clé PROTOTYPES : correspond à xsubppLes options « -prototypes » et « -noprototypes » de.
Ce mot-clé remplace les options de ligne de commande. Les prototypes sont activés par défaut. Lorsque
Les prototypes sont activés. Les XSUB recevront des prototypes Perl. Ce mot-clé peut être utilisé.
plusieurs fois dans un module XS pour activer et désactiver les prototypes pour différentes parties du
module.

Pour activer les prototypes :

PROTOTYPES : ACTIVER

Pour désactiver les prototypes :

PROTOTYPES : DÉSACTIVER

Le manuel de formation PROTOTYPE: Mots-clés
Ce mot-clé est similaire au mot-clé PROTOTYPES : ci-dessus, mais peut être utilisé pour forcer xsubpp
Pour utiliser un prototype spécifique pour le XSUB. Ce mot-clé remplace tous les autres prototypes.
Options et mots-clés, mais n'affecte que le XSUB actuel. Consultez « Prototypes » dans perlsub.
pour plus d'informations sur les prototypes Perl.

bool_t
rpcb_gettime(timep, ...)
time_t timep = NO_INIT
PROTOTYPE : $;$
PREINIT :
char *host = "localhost";
CODE:
si( éléments > 1 )
hôte = (char *)SvPV_nolen(ST(1));
RETVAL = rpcb_gettime( hôte, &timep );
SORTIE:
heure
RETOUR

Si les prototypes sont activés, vous pouvez les désactiver localement pour un XSUB donné comme dans le
exemple suivant :

annuler
rpcb_gettime_noproto()
PROTOTYPE : DÉSACTIVER
...

Le manuel de formation ALIAS: Mots-clés
Le mot-clé ALIAS : permet à un XSUB d'avoir deux ou plusieurs noms Perl uniques et de savoir lesquels
de ces noms a été utilisé lors de son appel. Les noms Perl peuvent être entièrement qualifiés avec
Noms de paquets. Chaque alias est indexé. Le compilateur configurera une variable appelée
« ix » contenant l'index de l'alias utilisé. Lorsque la XSUB est appelée avec
son nom déclaré "ix" sera 0.

L'exemple suivant créera les alias « FOO::gettime() » et « BAR::getit() » pour cela
la fonction.

bool_t
rpcb_gettime(hôte,timep)
char *hôte
temps_t &tempsp
ALIAS:
FOO::gettime = 1
BAR::getit = 2
INIT :
printf("# ix = %d\n", ix );
SORTIE:
heure

Le manuel de formation SURCHARGE: Mots-clés
Au lieu d'écrire une interface surchargée en utilisant du Perl pur, vous pouvez également utiliser OVERLOAD
mot-clé pour définir des noms Perl supplémentaires pour vos fonctions (comme le mot-clé ALIAS :
ci-dessus). Cependant, les fonctions surchargées doivent être définies avec trois paramètres (sauf
pour nomethod() fonction nécessitant quatre paramètres). Si une fonction possède le
SURCHARGE : mot-clé, plusieurs lignes supplémentaires seront définies dans le fichier c généré par
xsubpp afin de s'enregistrer avec la magie de surcharge.

Étant donné que les objets bénis sont en fait stockés sous forme de RV, il est utile d'utiliser la table de types
fonctionnalités permettant de prétraiter les paramètres et d'extraire le SV réel stocké dans le RV béni.
Voir l'exemple pour T_PTROBJ_SPECIAL ci-dessous.

Pour utiliser le mot-clé OVERLOAD : créez une fonction XS qui prend trois paramètres d’entrée (
ou utilisez la définition de style c '...') comme ceci :

SV *
cmp (lobj, robj, swap)
Mon_Module_obj lobj
Mon_Module_obj robj
échange IV
SURCHARGE : cmp <=>
{ /* fonction définie ici */}

Dans ce cas, la fonction surchargera les deux opérateurs de comparaison à trois voies.
toutes les opérations de surcharge utilisant des caractères non alphabétiques, vous devez saisir le paramètre sans
entre guillemets, en séparant les surcharges multiples par des espaces. Notez que « » (la chaîne de caractères
(surcharge) doit être saisi comme \"\" (c'est-à-dire échappé).

Le manuel de formation RETOMBER: Mots-clés
En plus du mot-clé OVERLOAD, si vous devez contrôler la façon dont Perl génère automatiquement les données manquantes
opérateurs surchargés, vous pouvez définir le mot-clé FALLBACK dans la section d'en-tête du module, comme
ce:

MODULE = RPC PACKAGE = RPC

REPLI : VRAI
...

où FALLBACK peut prendre l'une des trois valeurs suivantes : VRAI, FAUX ou UNDEF. Si vous ne définissez pas
Si la valeur FALLBACK est utilisée lors de l'utilisation de OVERLOAD, la valeur par défaut est UNDEF. FALLBACK n'est pas utilisé, sauf
lorsqu'une ou plusieurs fonctions utilisant OVERLOAD ont été définies. Voir « fallback » dans
surcharge pour plus de détails.

Le manuel de formation INTERFACE: Mots-clés
Ce mot-clé déclare le XSUB actuel comme détenteur de la signature d'appel donnée. Si
un texte suit ce mot-clé, il est considéré comme une liste de fonctions qui ont ceci
signature et doit être joint au XSUB actuel.

Par exemple, si vous avez 4 fonctions C multiplier(), diviser(), ajouter(), soustraire() tous ayant
la signature:

symbolique f(symbolique, symbolique);

vous pouvez les faire tous utiliser le même XSUB en utilisant ceci :

symbolique
interface_s_ss(arg1, arg2)
arg1 symbolique
arg2 symbolique
INTERFACE:
multiplier diviser
additionner soustraire

(Ceci est le code XSUB complet pour 4 fonctions Perl !) Quatre fonctions Perl générées partagent
noms avec fonctions C correspondantes.

L'avantage de cette approche par rapport au mot-clé ALIAS: est qu'il n'est pas nécessaire de
code une instruction switch, chaque fonction Perl (qui partage le même XSUB) sait quelle instruction C
fonction à appeler. On peut également ajouter une fonction supplémentaire. reste() at
exécution en utilisant

CV *mycv = newXSproto("Symbolique::reste",
XS_Symbolic_interface_s_ss, __FILE__, "$$");
XSINTERFACE_FUNC_SET(mycv, reste);

disons, à partir d'un autre XSUB. (Cet exemple suppose qu'il n'y avait pas d'INTERFACE_MACRO :
section, sinon il faut utiliser autre chose à la place de « XSINTERFACE_FUNC_SET », voir
la section suivante.)

Le manuel de formation INTERFACE_MACRO : Mots-clés
Ce mot clé permet de définir une INTERFACE en utilisant une manière différente d'extraire une fonction
Pointeur d'une XSUB. Le texte qui suit ce mot-clé doit indiquer le nom des macros.
qui extrairait/définirait un pointeur de fonction. La macro d'extraction reçoit un type de retour,
« CV* » et « XSANY.any_dptr » pour ce « CV* ». La macro setter reçoit cv et le
pointeur de fonction.

Les valeurs par défaut sont « XSINTERFACE_FUNC » et « XSINTERFACE_FUNC_SET ». Un mot-clé INTERFACE
avec une liste vide de fonctions peut être omise si le mot-clé INTERFACE_MACRO est utilisé.

Supposons que dans l'exemple précédent, les fonctions pointent vers multiplier(), diviser(), ajouter(),
soustraire() sont conservés dans un tableau C global « fp[] » avec des décalages « multiply_off »,
« diviser_off », « ajouter_off », « soustraire_off ». On peut alors utiliser

#define XSINTERFACE_FUNC_BYOFFSET(ret,cv,f) \
((XSINTERFACE_CVT_ANON(ret))fp[CvXSUBANY(cv).any_i32])
#define XSINTERFACE_FUNC_BYOFFSET_set(cv,f) \
CvXSUBANY(cv).any_i32 = CAT2( f, _off )

en césarienne,

symbolique
interface_s_ss(arg1, arg2)
arg1 symbolique
arg2 symbolique
INTERFACE_MACRO :
XSINTERFACE_FUNC_BYOFFSET
XSINTERFACE_FUNC_BYOFFSET_set
INTERFACE:
multiplier diviser
additionner soustraire

dans la section XSUB.

Le manuel de formation COMPRENDRE: Mots-clés
Ce mot-clé peut être utilisé pour extraire d'autres fichiers dans le module XS. Ces autres fichiers peuvent contenir
Code XS. INCLURE : peut également être utilisé pour exécuter une commande afin de générer le code XS à extraire.
dans le module.

Le fichier Rpcb1.xsh contient notre fonction « rpcb_gettime() » :

bool_t
rpcb_gettime(hôte,timep)
char *hôte
temps_t &tempsp
SORTIE:
heure

Le module XS peut utiliser INCLUDE : pour y insérer ce fichier.

INCLURE : Rpcb1.xsh

Si les paramètres du mot-clé INCLUDE: sont suivis d'un tube ("|"), le compilateur
interprétera les paramètres comme une commande. Cette fonctionnalité est légèrement déconseillée au profit de
la directive « INCLUDE_COMMAND: », comme documenté ci-dessous.

INCLURE : cat Rpcb1.xsh |

N'utilisez pas ceci pour exécuter perl : « INCLUDE : perl | » exécutera le perl qui se trouve être le
Le premier de votre chemin, et pas nécessairement le même Perl que celui utilisé pour exécuter « xsubpp ». Voir
« Le mot-clé INCLUDE_COMMAND : ».

Le manuel de formation INCLURE_COMMANDE : Mots-clés
Exécute la commande fournie et inclut sa sortie dans le document XS actuel.
"INCLUDE_COMMAND" attribue une signification particulière au jeton $^X dans la mesure où il exécute le même perl
interpréteur qui exécute « xsubpp » :

INCLUDE_COMMAND : cat Rpcb1.xsh

INCLURE_COMMANDE : $^X -e ...

Le manuel de formation CAS: Mots-clés
Le mot-clé CASE : permet à un XSUB d'avoir plusieurs parties distinctes, chaque partie agissant comme
un XSUB virtuel. CAS : est gourmand et s'il est utilisé, tous les autres mots-clés XS doivent être
contenu dans un CASE : Cela signifie que rien ne peut précéder le premier CASE : dans le XSUB et
tout ce qui suit le dernier CASE: est inclus dans ce cas.

UN CAS : peut basculer via un paramètre du XSUB, via la variable ALIAS « ix » (voir « Le
ALIAS : Mot-clé »), ou peut-être via la variable « éléments » (voir « Paramètre de longueur variable
Listes"). Le dernier CAS : devient le défaut cas s'il n'est pas associé à un
conditionnel. L'exemple suivant montre la commutation de la casse via « ix » avec une fonction
« rpcb_gettime() » ayant un alias « x_gettime() ». Lorsque la fonction est appelée comme
"rpcb_gettime()" ses paramètres sont les habituels "(char *host, time_t *timep)", mais lorsque le
la fonction est appelée "x_gettime()" ses paramètres sont inversés, "(time_t *timep, char
*hôte)".

Long
rpcb_gettime(a,b)
CAS : ix == 1
ALIAS:
x_gettime = 1
ENTREE:
# 'a' est timep, 'b' est l'hôte
char *b
time_t a = NO_INIT
CODE:
RETVAL = rpcb_gettime( b, &a );
SORTIE:
a
RETOUR
CAS:
# 'a' est l'hôte, 'b' est timep
char *a
time_t &b = NO_INIT
SORTIE:
b
RETOUR

Cette fonction peut être appelée avec l'une des instructions suivantes. Notez les différences
listes d'arguments.

$status = rpcb_gettime( $hôte, $timep );

$status = x_gettime( $timep, $host );

Le manuel de formation EXPORT_XSUB_SYMBOLES : Mots-clés
Le mot-clé EXPORT_XSUB_SYMBOLS: est probablement quelque chose dont vous n'aurez jamais besoin. En Perl
Pour les versions antérieures à la version 5.16.0, ce mot-clé est sans effet. À partir de la version 5.16, les symboles XSUB
ne sont plus exportées par défaut. Ce sont donc des fonctions « statiques ». Si vous incluez

EXPORT_XSUB_SYMBOLS : ACTIVER

Dans votre code XS, les XSUB suivant cette ligne ne seront pas déclarés « statiques ». Vous pouvez
désactiver plus tard ceci avec

EXPORT_XSUB_SYMBOLS : DÉSACTIVER

Ce qui, encore une fois, est la valeur par défaut que vous ne devriez probablement jamais modifier. Vous ne pouvez pas l'utiliser.
mot-clé sur les versions de perl antérieures à 5.16 pour rendre les XSUB « statiques ».

Le manuel de formation & Unaire Opérateur
L'opérateur unaire « & » dans la section INPUT : est utilisé pour indiquer xsubpp qu'il devrait convertir
une valeur Perl vers/depuis C en utilisant le type C à gauche de « & », mais fournir un pointeur vers ceci
valeur lorsque la fonction C est appelée.

Ceci est utile pour éviter un bloc CODE: pour une fonction C qui prend un paramètre par
référence. En règle générale, le paramètre ne doit pas être de type pointeur (un « int » ou un « long »), mais
pas un "int*" ou "long*").

Le XSUB suivant générera un code C incorrect. xsubpp le compilateur transformera ceci
dans le code qui appelle "rpcb_gettime()" avec les paramètres "(char *host, time_t timep)", mais
le vrai "rpcb_gettime()" veut que le paramètre "timep" soit de type "time_t*" plutôt que
"temps_t".

bool_t
rpcb_gettime(hôte,timep)
char *hôte
temps_t tempsp
SORTIE:
heure

Ce problème est corrigé en utilisant l'opérateur « & ». xsubpp le compilateur va maintenant tourner
ceci dans le code qui appelle correctement "rpcb_gettime()" avec les paramètres "(char *host, time_t
*timep)". Il le fait en conservant le « & », donc l'appel de fonction ressemble à
"rpcb_gettime(hôte, &timep)".

bool_t
rpcb_gettime(hôte,timep)
char *hôte
temps_t &tempsp
SORTIE:
heure

Insertion COSSE, Commentaires et C Préprocesseur Directives
Les directives du préprocesseur C sont autorisées dans BOOT:, PREINIT: INIT:, CODE:, PPCODE:,
Blocs POSTCALL et CLEANUP, ainsi qu'en dehors des fonctions. Les commentaires sont autorisés.
n'importe où après le mot-clé MODULE. Le compilateur transmettra les directives du préprocesseur.
sans modification et supprimera les lignes commentées. La documentation POD est autorisée à tout moment.
Point, dans les sections C et XS. POD doit être terminé par « =cut ».
commande ; « xsubpp » se terminera avec une erreur si ce n'est pas le cas. Il est très peu probable que l'exécution humaine
le code C généré sera confondu avec le POD, car la plupart des styles d'indentation génèrent des espaces
devant toute ligne commençant par « = ». Les fichiers XS générés automatiquement peuvent tomber dans ce piège.
à moins que l'on prenne soin de s'assurer qu'un espace interrompe la séquence "\n=".

Des commentaires peuvent être ajoutés aux XSUB en plaçant un « # » comme premier espace non blanc d'une ligne.
Il faut veiller à ne pas donner l’impression que le commentaire est une directive de préprocesseur C,
de peur qu'il soit interprété comme tel. Le moyen le plus simple d'éviter cela est d'insérer des espaces
devant le "#".

Si vous utilisez des directives de préprocesseur pour choisir l'une des deux versions d'une fonction, utilisez

#si ... version1
#else /* ... version2 */
#endif

ne le comptant pas

#si ... version1
#endif
#si ... version2
#endif

parce que sinon xsubpp croiront que vous avez fait une définition en double du
fonction. Ajoutez également une ligne vide avant #else/#endif afin qu'elle ne soit pas considérée comme faisant partie de la fonction.
du corps de la fonction.

En utilisant XS et C + +
Si un nom XSUB contient « :: », il est considéré comme une méthode C++. Le Perl généré
La fonction suppose que son premier argument est un pointeur d'objet. Le pointeur d'objet
sera stocké dans une variable nommée THIS. L'objet aurait dû être créé en C++ avec
le Nouveau() fonction et devrait être béni par Perl avec le sv_setref_pv() macro. Le
La validation de l'objet par Perl peut être gérée par une table de types. Un exemple de table de types est présenté.
à la fin de cette section.

Si le type de retour du XSUB inclut « static », la méthode est considérée comme statique.
méthode. Il appellera la fonction C++ en utilisant la classe::méthode() syntaxe. Si la méthode est
non statique, la fonction sera appelée en utilisant THIS->méthode() syntaxe.

Les exemples suivants utiliseront la classe C++ suivante.

couleur de classe {
publique:
couleur();
~couleur();
int bleu();
void set_blue( int );

privé:
int c_bleu;
};

Les XSUB pour le bleu() et set_blue() les méthodes sont définies avec le nom de la classe mais le
le paramètre pour l'objet (THIS ou « self ») est implicite et n'est pas répertorié.

int
couleur::bleu()

annuler
couleur::set_blue( val )
valeur int

Les deux fonctions Perl attendent un objet comme premier paramètre. Dans le code C++ généré
le code de l'objet s'appelle "THIS", et l'appel de méthode sera effectué sur cet objet.
Donc, dans le code C++, le bleu() et set_blue() les méthodes seront appelées comme ceci :

RETVAL = CECI->bleu();

CECI->set_blue( val );

Vous pouvez également écrire une seule méthode get/set en utilisant un argument facultatif :

int
couleur::bleu( val = NO_INIT )
valeur int
PROTOTYPE $;$
CODE:
si (éléments > 1)
CECI->set_blue( val );
RETVAL = CECI->bleu();
SORTIE:
RETOUR

Si le nom de la fonction est DETRUIRE alors la fonction C++ "delete" sera appelée et "THIS"
sera donné comme paramètre. Le code C++ généré pour

annuler
couleur::DÉTRUIRE()

ressemblera à ceci:

couleur *THIS = ...; // Initialisé comme dans typemap

supprimer CECI;

Si le nom de la fonction est nouvelle alors la fonction C++ "new" sera appelée pour créer un
Objet C++ dynamique. Le XSUB attendra le nom de la classe, qui sera conservé dans une variable.
appelé « CLASSE », à donner comme premier argument.

couleur *
couleur::nouveau()

Le code C++ généré appellera « nouveau ».

RETVAL = nouvelle couleur();

Voici un exemple de typemap qui pourrait être utilisé pour cet exemple C++.

CARTE DE TYPE
couleur * O_OBJECT

SORTIE
# L'objet Perl est béni dans 'CLASS', qui devrait être un
# char* ayant le nom du package pour la bénédiction.
O_OBJET
sv_setref_pv( $arg, CLASSE, (void*)$var );

CONTRIBUTION
O_OBJET
si( sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG) )
$var = ($type)SvIV((SV*)SvRV( $arg ));
sinon {
avertir("${Package}::$func_name() -- " .
"$var n'est pas une référence SV bénie");
XSRETURN_UNDEF ;
}

Interface de Marketing
Lors de la conception d'une interface entre Perl et une bibliothèque C, une traduction directe de C vers
XS (tel que créé par « h2xs -x ») est souvent suffisant. Cependant, il arrive que l'interface
ressemblera beaucoup à du C et sera parfois non intuitif, en particulier lorsque la fonction C
modifie l'un de ses paramètres ou renvoie un échec dans la bande passante (comme dans « valeurs de retour négatives »)
« échec moyen »). Dans les cas où le programmeur souhaite créer une interface plus proche de Perl
la stratégie suivante peut aider à identifier les parties les plus critiques de l'interface.

Identifiez les fonctions C avec des paramètres d'entrée/sortie ou de sortie. Les XSUB correspondants
les fonctions peuvent être capables de renvoyer des listes à Perl.

Identifiez les fonctions C qui utilisent certaines informations intrabande comme indicateur d'échec. Elles peuvent
être candidats pour renvoyer une liste indéfinie ou vide en cas d'échec. Si l'échec peut être
détecté sans appel à la fonction C, vous souhaiterez peut-être utiliser une section INIT : pour signaler
l'échec. Pour les échecs détectables après le retour de la fonction C, on peut utiliser un
Section POSTCALL : pour traiter l'échec. Dans les cas plus complexes, utilisez CODE : ou PPCODE :
sections.

Si de nombreuses fonctions utilisent la même indication d'échec en fonction de la valeur de retour, vous souhaiterez peut-être
pour créer un typedef spécial pour gérer cette situation. Mettez

typedef int negative_is_failure;

près du début du fichier XS et créez une entrée de typemap OUTPUT pour
"negative_is_failure" qui convertit les valeurs négatives en "undef", ou peut-être crever()s. Après
cette valeur de retour de type « negative_is_failure » créera une interface plus proche de Perl.

Identifiez les valeurs utilisées uniquement par les fonctions C et XSUB elles-mêmes, par exemple, lorsqu'un
Le paramètre d'une fonction doit être le contenu d'une variable globale. Si Perl n'en a pas besoin,
pour accéder au contenu de la valeur, il n'est peut-être pas nécessaire de fournir une traduction
pour cette valeur de C à Perl.

Identifiez les pointeurs dans les listes de paramètres et les valeurs de retour des fonctions C. Quelques pointeurs
peuvent être utilisés pour implémenter des paramètres d'entrée/sortie ou de sortie, ils peuvent être gérés dans XS avec
l'opérateur unaire « & » et, éventuellement, le mot-clé NO_INIT. D'autres le feront.
nécessitent la gestion de types comme « int * », et il faut décider quel type Perl est utile.
Dans ce cas, une traduction suffira. Lorsque la sémantique est claire, il est conseillé de mettre
la traduction dans un fichier typemap.

Identifiez les structures utilisées par les fonctions C. Dans de nombreux cas, il peut être utile d'utiliser
la table de types T_PTROBJ pour ces structures afin qu'elles puissent être manipulées par Perl comme bénies
objets. (Ceci est géré automatiquement par « h2xs -x ».)

Si le même type C est utilisé dans plusieurs contextes différents qui nécessitent des
traductions, « typedef » plusieurs nouveaux types mappés à ce type C, et créent des
carte de type entrées pour ces nouveaux types. Utilisez ces types dans les déclarations de type de retour et
paramètres aux XSUB.

Perl Objets Et C Structure
Lorsqu'il s'agit de structures C, il faut sélectionner soit T_PTROBJ or T_PTRREF pour le XS
type. Ces deux types sont conçus pour gérer des pointeurs vers des objets complexes. Le type T_PTRREF
permettra à l'objet Perl d'être dé-béni alors que le type T_PTROBJ nécessite que le
L'objet doit être béni. En utilisant T_PTROBJ, on peut réaliser une forme de vérification de type, car
XSUB tentera de vérifier que l'objet Perl est du type attendu.

Le code XS suivant montre le getnetconfigent() fonction utilisée avec ONC+ TIRPC.
Le manuel de formation getnetconfigent() la fonction renverra un pointeur vers une structure C et aura le C
Le prototype est présenté ci-dessous. Cet exemple illustre comment le pointeur C devient un pointeur Perl.
référence. Perl considérera cette référence comme un pointeur vers un objet béni et
Tenter d'appeler un destructeur pour l'objet. Un destructeur sera fourni dans le fichier XS.
source pour libérer la mémoire utilisée par getnetconfigent()Les destructeurs dans XS peuvent être créés par
spécifier une fonction XSUB dont le nom se termine par le mot DETRUIRELes destructeurs XS peuvent être
utilisé pour libérer de la mémoire qui peut avoir été allouée par un autre XSUB.

struct netconfig *getnetconfigent(const char *netid);

Un « typedef » sera créé pour « struct netconfig ». L'objet Perl sera validé dans un
classe correspondant au nom du type C, avec la balise « Ptr » ajoutée, et le nom doit
Ne pas inclure d'espaces s'il s'agit d'un nom de paquet Perl. Le destructeur sera placé
dans une classe correspondant à la classe de l'objet et le mot clé PREFIX sera utilisé pour
coupez le nom avec le mot DESTROY comme Perl s'y attend.

typedef struct netconfig Netconfig;

MODULE = RPC PACKAGE = RPC

Netconfig *
getnetconfigent(netid)
char *netid

MODULE = RPC PACKAGE = NetconfigPtr PRÉFIXE = rpcb_

annuler
rpcb_DESTROY(netconf)
Netconfig *netconf
CODE:
printf("Maintenant dans NetconfigPtr::DESTROY\n");
gratuit( netconf );

Cet exemple nécessite l'entrée de typemap suivante. Consultez perlxstypemap pour plus d'informations.
informations sur l'ajout de nouveaux types de mappages pour une extension.

CARTE DE TYPE
Netconfig * T_PTROBJ

Cet exemple sera utilisé avec les instructions Perl suivantes.

utiliser RPC ;
$netconf = getnetconfigent("udp");

Lorsque Perl détruit l'objet référencé par $netconf, il envoie l'objet au
Fonction XSUB DESTROY fournie. Perl ne peut pas déterminer, et ne s'en soucie pas, que cela
object est une structure C et non un objet Perl. En ce sens, il n'y a aucune différence entre
l'objet créé par le getnetconfigent() XSUB et un objet créé par un Perl normal
sous-programme.

Sans encombre Stockage Statique Date in XS
À partir de Perl 5.8, un framework macro a été défini pour permettre aux données statiques d'être
stockés en toute sécurité dans des modules XS qui seront accessibles à partir d'un Perl multithread.

Bien que principalement conçues pour être utilisées avec Perl multithread, les macros ont été
conçus pour fonctionner également avec Perl non threadé.

Il est donc fortement recommandé que ces macros soient utilisées par tous les modules XS qui font
utilisation de données statiques.

Le moyen le plus simple d'obtenir un ensemble de modèles de macros à utiliser est de spécifier le « -g »
Option ("--global") avec h2xs (voir h2xs).

Vous trouverez ci-dessous un exemple de module qui utilise les macros.

#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

/* Données globales */

#define MY_CXT_KEY "BlindMice::_guts" XS_VERSION

typedef struct {
nombre int;
nom du caractère[3][100];
} mon_cxt_t;

DÉMARRER_MON_CXT

MODULE = BlindMice PACKAGE = BlindMice

BATEAU:
{
MON_CXT_INIT;
MY_CXT.count = 0;
strcpy(MY_CXT.name[0], "Aucun");
strcpy(MY_CXT.name[1], "Aucun");
strcpy(MY_CXT.name[2], "Aucun");
}

int
newMouse(char * nom)
PREINIT :
dMY_CXT;
CODE:
si (MY_CXT.count >= 3) {
warn("J'ai déjà 3 souris aveugles");
RETVAL = 0 ;
}
else {
RETVAL = ++ MY_CXT.count;
strcpy(MY_CXT.name[MY_CXT.count - 1], nom);
}
SORTIE:
RETOUR

char *
get_mouse_name(index)
indice entier
PREINIT :
dMY_CXT;
CODE:
si (index > MY_CXT.count)
croak("Il n'y a que 3 souris aveugles.");
d'autre
RETVAL = MY_CXT.nom[index - 1];
SORTIE:
RETOUR

annuler
CLONER(...)
CODE:
MON_CXT_CLONE;

MON_CXT RÉFÉRENCE

MA_CXT_KEY
Cette macro est utilisée pour définir une clé unique pour faire référence aux données statiques d'un XS
module. Le schéma de nommage suggéré, tel qu'utilisé par h2xs, consiste à utiliser une chaîne qui
se compose du nom du module, de la chaîne "::_guts" et du numéro de version du module.

#define MY_CXT_KEY "MonModule::_guts" XS_VERSION

typedef my_cxt_t
Ce typedef de structure doit s'appellera toujours « my_cxt_t ». Les autres macros « CXT* » supposent
l'existence du nom de typedef "my_cxt_t".

Déclarez un typedef nommé « my_cxt_t » qui est une structure contenant toutes les données
cela doit être local pour l'interprète.

typedef struct {
int une_valeur;
} mon_cxt_t;

DÉMARRER_MON_CXT
Placez toujours la macro START_MY_CXT directement après la déclaration de « my_cxt_t ».

MON_CXT_INIT
La macro MY_CXT_INIT initialise le stockage pour la structure « my_cxt_t ».

It doit être appelé une seule fois, généralement dans une section BOOT:. Si vous maintenez
plusieurs interprètes, il doit être appelé une fois dans chaque instance d'interpréteur, sauf
Pour les interpréteurs clonés à partir d'interpréteurs existants. (Voir « MY_CXT_CLONE » ci-dessous.)

dMY_CXT
Utilisez la macro dMY_CXT (une déclaration) dans toutes les fonctions qui accèdent à MY_CXT.

MON_CXT
Utilisez la macro MY_CXT pour accéder aux membres de la structure « my_cxt_t ». Par exemple, si
"my_cxt_t" est

typedef struct {
index int;
} mon_cxt_t;

puis utilisez ceci pour accéder au membre « index »

dMY_CXT;
MY_CXT.index = 2;

aMY_CXT/pMY_CXT
"dMY_CXT" peut être assez coûteux à calculer, et pour éviter la surcharge liée à l'invocation
dans chaque fonction il est possible de passer la déclaration à d'autres fonctions en utilisant
les macros "aMY_CXT"/"pMY_CXT", par exemple

void sub1() {
dMY_CXT;
MY_CXT.index = 1;
sub2(aMY_CXT);
}

vide sub2(pMY_CXT) {
MY_CXT.index = 2;
}

De manière analogue à « pTHX », il existe des formes équivalentes lorsque la macro est la première ou
dernier dans plusieurs arguments, où un trait de soulignement représente une virgule, c'est-à-dire "_aMY_CXT",
"aMY_CXT_", "_pMY_CXT" et "pMY_CXT_".

MON_CXT_CLONE
Par défaut, lorsqu'un nouvel interpréteur est créé en tant que copie d'un interpréteur existant (par exemple via
"threads->create()"), les deux interpréteurs partagent la même structure physique my_cxt_t.
L'appel de « MY_CXT_CLONE » (généralement via la fonction « CLONE() » du package) provoque un
copie octet par octet de la structure à prendre, et tout dMY_CXT futur provoquera
la copie à laquelle il faut accéder à la place.

MY_CXT_INIT_INTERP(mon_perl)
dMY_CXT_INTERP(mon_perl)
Ce sont des versions des macros qui prennent un interpréteur explicite comme argument.

Notez que ces macros ne fonctionneront ensemble qu'au sein du même fichier source ; c'est-à-dire un
dMY_CTX dans un fichier source accédera à une structure différente d'un dMY_CTX dans un autre
fichier source.

Tenant compte des threads Système interfaces
À partir de Perl 5.8, au niveau C/C++, Perl sait comment encapsuler les interfaces système/bibliothèque
qui ont des versions prenant en charge les threads (par exemple getpwent_r()) dans les macros frontales (par exemple obtenir ())
qui gèrent correctement l'interaction multithread avec l'interpréteur Perl. Cela
cela se produit de manière transparente, la seule chose que vous devez faire est d'instancier un interpréteur Perl.

Cet emballage se produit toujours lors de la compilation du code source principal de Perl (PERL_CORE est défini) ou du
Extensions du noyau Perl (PERL_EXT est défini). Lors de la compilation de code XS hors du noyau Perl
L'emballage n'a pas lieu. Notez cependant que le mélange des formes _r (comme Perl)
compilé pour une opération multithread fera l'affaire) et les formes _r-less ne sont ni bien
définis (des résultats incohérents, une corruption des données ou même des plantages deviennent plus probables), ni
est-ce très portable.

EXEMPLES


Fichier « RPC.xs » : interface vers certaines fonctions de la bibliothèque de liaison ONC+ RPC.

#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#inclure

typedef struct netconfig Netconfig;

MODULE = RPC PACKAGE = RPC

SV *
rpcb_gettime(hôte="localhost")
char *hôte
PREINIT :
temps_t tempsp;
CODE:
ST(0) = sv_newmortal();
si( rpcb_gettime( hôte, &timep ) )
sv_setnv( ST(0), (double)tempsp );

Netconfig *
getnetconfigent(netid="udp")
char *netid

MODULE = RPC PACKAGE = NetconfigPtr PRÉFIXE = rpcb_

annuler
rpcb_DESTROY(netconf)
Netconfig *netconf
CODE:
printf("NetconfigPtr::DÉTRUIRE\n");
gratuit( netconf );

Fichier « typemap » : mappage de types personnalisé pour RPC.xs. (cf. perlxstypemap)

CARTE DE TYPE
Netconfig * T_PTROBJ

Fichier « RPC.pm » : module Perl pour l'extension RPC.

paquet RPC;

Exiger l'exportateur ;
nécessite DynaLoader ;
@ISA = qw(Exportateur DynaLoader);
@EXPORT = qw(rpcb_gettime getnetconfigent);

RPC d'amorçage ;
1;

Fichier « rpctest.pl » : programme de test Perl pour l'extension RPC.

utiliser RPC ;

$netconf = getnetconfigent();
$a = rpcb_gettime();
imprimer "temps = $a\n";
imprimer "netconf = $netconf\n";

$netconf = getnetconfigent("tcp");
$a = rpcb_gettime("peuplier");
imprimer "temps = $a\n";
imprimer "netconf = $netconf\n";

MISES EN GARDE


Le code XS a un accès complet aux appels système, y compris aux fonctions de la bibliothèque C. Il a donc le
capacité d'interférer avec les éléments que le noyau Perl ou d'autres modules ont mis en place,
tels que les gestionnaires de signaux ou les descripteurs de fichiers. Cela pourrait perturber la mémoire, ou tout autre
choses nocives. Ne le fais pas.

Certains modules disposent d'une boucle d'événements, attendant une saisie utilisateur. Il est très peu probable que deux
de tels modules fonctionneraient correctement ensemble dans une seule application Perl.

En général, l'interpréteur Perl se considère comme le centre de l'univers en ce qui concerne
Le programme Perl est en marche. Le code XS est considéré comme un assistant, permettant d'accomplir des tâches que Perl
ne fonctionne pas, ou pas assez vite, mais toujours subordonné à Perl. Le code XS le plus proche
Si l’on adhère à ce modèle, moins il y aura de conflits.

Un domaine où il y a eu des conflits concerne les paramètres régionaux C. (Voir perllocale.)
perl, à une exception près et sauf indication contraire, définit les paramètres régionaux sous-jacents
programme s'exécute dans les paramètres régionaux qui lui sont transmis par l'environnement. Il s'agit d'un
différence importante par rapport à un programme générique en langage C, où les paramètres régionaux sous-jacents sont les
Les paramètres régionaux « C » sont définis, sauf si le programme les modifie. Depuis la version 5.20, ces paramètres régionaux sous-jacents sont
complètement caché du code perl pur en dehors de la portée lexicale de « utiliser les paramètres régionaux » à l'exception de
quelques appels de fonctions dans le module POSIX qui l'utilisent nécessairement. Mais le
paramètres régionaux sous-jacents, à cette exception près, sont exposés au code XS, affectant toute la bibliothèque C
routines dont le comportement dépend des paramètres régionaux. Il est préférable que votre code XS ne présume pas que
La locale sous-jacente est « C ». L'exception est la catégorie locale « LC_NUMERIC » et la
La raison pour laquelle il s'agit d'une exception est que l'expérience a montré que cela peut être problématique pour XS
code, alors que nous n'avons pas eu de rapports de problèmes avec les autres catégories de paramètres régionaux. Et
la raison pour laquelle cette catégorie est problématique est que le caractère utilisé comme décimal
Le point peut varier. De nombreuses langues européennes utilisent une virgule, tandis que l'anglais, et donc Perl,
attend un point (U+002E : POINT). De nombreux modules ne gèrent que le caractère de base.
étant un point, Perl tente donc de le rendre tel. Jusqu'à Perl v5.20, la tentative était
simplement de définir « LC_NUMERIC » au démarrage sur la locale « C ». setlocale() autrement
le modifierait ; cela a entraîné quelques échecs. Par conséquent, à partir de la version 5.22, Perl tente de
gardez toujours « LC_NUMERIC » défini sur « C » pour le code XS.

Pour résumer, voici à quoi s'attendre et comment gérer les paramètres régionaux dans le code XS :

Code XS non sensible aux paramètres régionaux
Gardez à l'esprit que même si vous pensez que votre code n'est pas sensible aux paramètres régionaux, il peut appeler un C
fonction de bibliothèque. Espérons que la page de manuel d'une telle fonction l'indiquera.
cette dépendance, mais la documentation est imparfaite.

Les paramètres régionaux actuels sont exposés au code XS, à l'exception peut-être de « LC_NUMERIC » (expliqué dans
(paragraphe suivant). Aucun problème n'a été signalé avec les autres
catégories. Perl initialise les éléments au démarrage afin que la locale actuelle soit celle
qui est indiqué par l'environnement de l'utilisateur en vigueur à ce moment-là. Voir
"ENVIRONNEMENT" en perllocale.

Cependant, jusqu'à la version 5.20, Perl initialisait les choses au démarrage de sorte que « LC_NUMERIC »
était défini sur la locale « C ». Mais si un code quelconque le modifiait, il resterait
modifié. Cela signifie que votre module ne peut pas compter sur « LC_NUMERIC » comme étant quelque chose dans
particulier, et vous ne pouvez pas vous attendre à ce que les nombres à virgule flottante (y compris les chaînes de version)
contiennent des points. Si vous n'autorisez pas les éléments sans point, votre code pourrait se casser si quelqu'un
La langue locale a été modifiée à chaque fois. C'est pourquoi la version 5.22 a modifié le comportement de Perl.
essaie de conserver « LC_NUMERIC » dans la locale « C », sauf autour des opérations internes
là où il devrait y avoir autre chose. Un code XS défaillant pourra toujours être modifié.
les paramètres régionaux de toute façon, mais l'instance la plus courante de ceci est vérifiée et gérée.

Code XS tenant compte des paramètres régionaux
Si les paramètres régionaux de l'environnement de l'utilisateur sont souhaités, XS ne devrait pas être nécessaire.
code pour définir les paramètres régionaux, à l'exception de « LC_NUMERIC », car Perl l'a déjà configuré. XS
le code doit éviter de modifier les paramètres régionaux, car cela peut affecter négativement d'autres éléments non liés,
code et peut ne pas être thread-safe. Cependant, certaines bibliothèques étrangères qui peuvent être appelées le sont
Définissez-le, par exemple « Gtk ». Cela peut entraîner des problèmes pour le noyau Perl et d'autres modules.
À partir de la version 5.20.1, appel de la fonction sync_locale() de XS devrait être suffisant
pour éviter la plupart de ces problèmes. Avant cela, vous avez besoin d'une instruction Perl pure qui
est ce que ca:

POSIX::setlocale(LC_ALL, POSIX::setlocale(LC_ALL));

Dans le cas où votre code XS pourrait avoir besoin des paramètres régionaux « LC_NUMERIC » sous-jacents, il existe
macros disponibles pour y accéder ; voir « Fonctions et macros liées aux paramètres régionaux » dans perlapi.

XS VERSION


Ce document couvre les fonctionnalités prises en charge par « ExtUtils::ParseXS » (également connu sous le nom de « xsubpp »)
3.13_01.

Utilisez perlxs en ligne avec les services onworks.net


Serveurs et postes de travail gratuits

Télécharger des applications Windows et Linux

Commandes Linux

Ad




×
Publicité
❤ ️Achetez, réservez ou achetez ici — gratuitement, contribue à maintenir la gratuité des services.