CONTENUS

  • NOM
  • DESCRIPTION
    • Anatomie d'une carte de type
    • Le rôle du fichier typemap dans votre distribution
    • Partage des cartes de caractères entre les distributions CPAN
    • Écriture des entrées de typemap
    • Liste complète des cartes typographiques de base

NAME

perlxstypemap - Cartographie des types Perl XS C/Perl

DESCRIPTION

Plus vous réfléchissez à l'interfaçage entre deux langages, plus vous vous rendez compte que la majorité de l'effort du programmeur doit aller à la conversion entre les structures de données qui sont natives de l'un ou l'autre des langages impliqués. Cela l'emporte sur d'autres questions telles que les différentes conventions d'appel, car l'espace du problème est beaucoup plus grand. Il y a simplement plus de façons de pousser des données dans la mémoire qu'il y a de façons d'implémenter un appel de fonction.

La tentative de Perl XS à une solution à ce problème est le concept de typemaps. À un niveau abstrait, une carte de type Perl XS n'est rien d'autre qu'une recette pour convertir une certaine structure de données Perl en une certaine structure de données C et vice versa. Étant donné qu'il peut y avoir des types C qui sont suffisamment similaires les uns aux autres pour justifier une conversion avec la même logique, les cartes de types XS sont représentées par un identifiant unique, désormais appelé type XS dans ce document. Vous pouvez alors indiquer au compilateur XS que plusieurs types C doivent être mappés avec le même typemap XS.

Dans votre code XS, lorsque vous définissez un argument avec un type C ou lorsque vous utilisez un type CODE: et un OUTPUT: ensemble avec un type de retour C de votre XSUB, ce sera le mécanisme de typemapping qui rendra cela facile.

Anatomie d'un typemap

En termes plus pratiques, la carte de type est une collection de fragments de code qui sont utilisés par le système de gestion de l'information. xsubpp pour faire correspondre les paramètres et les valeurs des fonctions C aux valeurs Perl. Le fichier typemap peut être constitué de trois sections étiquetées comme suit . TYPEMAP, INPUT, et OUTPUT. Une section initiale non étiquetée est supposée être une section TYPEMAP . La section INPUT indique au compilateur comment traduire les valeurs de Perl en variables de certains types C. La section OUTPUT indique au compilateur comment traduire les valeurs de certains types C en valeurs que Perl peut comprendre. La section TYPEMAP indique au compilateur lequel des fragments de code INPUT et OUTPUT doit être utilisé pour traduire un type C donné en une valeur Perl. Les étiquettes de la section TYPEMAP, INPUTou OUTPUT doivent commencer dans la première colonne sur une ligne par eux-mêmes, et doivent être en majuscules.

Chaque type de section peut apparaître un nombre arbitraire de fois et n'a pas à apparaître du tout. Par exemple, une carte de type peut couramment manquer de INPUT et OUTPUT si tout ce qu'elle doit faire est d'associer des types C supplémentaires à des types XS de base comme T_PTROBJ. Les lignes qui commencent par un dièse # sont considérées comme des commentaires et ignorées dans la section TYPEMAP mais sont considérées comme significatives dans la section INPUT et OUTPUT. Les lignes vides sont généralement ignorées.

Traditionnellement, les cartes typographiques devaient être écrites dans un fichier séparé, conventionnellement appelé typemap dans une distribution CPAN. Avec ExtUtils::ParseXS (le compilateur XS) version 3.12 ou mieux qui est livré avec perl 5.16, les cartes de types peuvent également être intégrées directement dans le code XS en utilisant une syntaxe de type HERE-doc :

TYPEMAP:<<HERE
...
HERE

HERE peut être remplacé par d'autres identifiants comme avec les HERE-docs Perl normaux. Tous les détails ci-dessous concernant le format textuel de la carte de type restent valables.

Le site TYPEMAP doit contenir une paire de type C et de type XS par ligne comme suit. Un exemple tiré du fichier typemap de base :

TYPEMAP
# all variants of char* is handled by the T_PV typemap
char *          T_PV
const char *    T_PV
unsigned char * T_PV
...

Le site INPUT et OUTPUT ont des formats identiques, c'est-à-dire que chaque ligne non indentée commence une nouvelle carte d'entrée ou de sortie respectivement. Une nouvelle carte d'entrée ou de sortie doit commencer par le nom du type XS à mettre en correspondance sur une ligne à part, suivi du code qui l'implémente en retrait sur les lignes suivantes. Exemple :

INPUT
T_PV
  $var=($type)SvPV_nolen($arg)
T_PTR
  $var= INT2PTR($type,SvIV($arg))

Nous verrons plus loin la signification de ces variables à l'allure de Perlish.

Enfin, voici un exemple de fichier typemap complet pour le mappage des chaînes de caractères C du type char * à des scalaires/chaînes de caractères Perl :

TYPEMAP
char *  T_PV

INPUT
T_PV
  $var=($type)SvPV_nolen($arg)

OUTPUT
T_PV
  sv_setpv((SV*)$arg,$var);

Voici un exemple plus compliqué : supposons que vous vouliez struct netconfig soit béni dans la classe Net::Config. Une façon de le faire est d'utiliser des traits de soulignement (_) pour séparer les noms de paquets, comme suit :

typedef struct netconfig * Net_Config;

Et ensuite fournir une entrée de carte de type T_PTROBJ_SPECIAL qui fait correspondre les traits de soulignement aux doubles points (: :), et déclare Net_Config comme étant de ce type :

TYPEMAP
Net_Config      T_PTROBJ_SPECIAL

INPUT
T_PTROBJ_SPECIAL
  if(sv_derived_from($arg,"${(my$ntt=$ntype)=~s/_/::/g;$ntt}")){
    IV tmp = SvIV((SV*)SvRV($arg));$var= INT2PTR($type, tmp);}else
    croak("$var is not of type ${(my$ntt=$ntype)=~s/_/::/g;$ntt}")

OUTPUT
T_PTROBJ_SPECIAL
  sv_setref_pv($arg,"${(my$ntt=$ntype)=~s/_/::/g;$ntt}",(void*)$var);

Les sections INPUT et OUTPUT substituent les underscores aux double-colonnes à la volée, donnant ainsi l'effet désiré. Cet exemple démontre une partie de la puissance et de la polyvalence de la fonction de carte de type.

Le site INT2PTR (définie dans perl.h) caste un entier vers un pointeur d'un type donné, en prenant soin de la possible différence de taille entre les entiers et les pointeurs. Il existe également PTR2IV, PTR2UV, PTR2NV macros, pour mapper dans l'autre sens, ce qui peut être utile dans les sections OUTPUT.

Le rôle du fichier typemap dans votre distribution.

Le typemap par défaut dans la distribution lib/ExtUtils du répertoire des sources Perl contient de nombreux types utiles qui peuvent être utilisés par les extensions Perl. Certaines extensions définissent des cartes de types supplémentaires qu'elles conservent dans leur propre répertoire. Ces cartes de types supplémentaires peuvent faire référence aux cartes INPUT et OUTPUT de la carte de types principale. Le site xsubpp permettra à la carte de type propre à l'extension de remplacer les mappages qui sont dans la carte de type par défaut. Au lieu d'utiliser une carte de type supplémentaire supplémentaire supplémentaire, les cartes de types peuvent être incorporées verbatim dans XS avec une syntaxe de type heredoc. Voir la documentation sur les TYPEMAP: mot-clé XS.

Pour les distributions CPAN, vous pouvez supposer que les types XS définis par le noyau de perl sont déjà disponibles. De plus, la carte de types du noyau possède des types XS par défaut pour un grand nombre de types C. Par exemple, si vous retournez simplement un char * à partir de votre XSUB, la carte de types du noyau aura ce type C associé au type XS T_PV. Cela signifie que votre chaîne de caractères C sera copiée dans le slot PV (valeur de pointeur) d'un nouveau scalaire qui sera retourné par votre XSUB à Perl.

Si vous développez une distribution CPAN utilisant XS, vous pouvez ajouter votre propre fichier appelé typemap à la distribution. Ce fichier peut contenir des cartes de types qui mappent des types spécifiques à votre code ou qui remplacent les mappages du fichier de cartes de types de base pour les types C communs.

Partage des cartes de types entre les distributions CPAN

À partir de la version 3.13_01 de ExtUtils::ParseXS (compatible avec perl 5.16 et mieux), il est assez facile de partager du code de typemap entre plusieurs distributions CPAN. L'idée générale est de le partager comme un module qui offre une certaine API et de faire en sorte que les modules dépendants déclarent cela comme une exigence de construction et importent la carte de type dans le XS. Un exemple d'un tel module de partage de typemap sur CPAN est le suivant . ExtUtils::Typemaps::Basic. Deux étapes pour obtenir les cartes de types de ce module disponibles dans votre code :

  • Déclarer ExtUtils::Typemaps::Basic comme une dépendance au moment de la construction dans Makefile.PL (utiliser BUILD_REQUIRES), ou dans votre Build.PL (utilisez build_requires).

  • Incluez la ligne suivante dans la section XS de votre fichier XS : (ne pas casser la ligne)

    INCLUDE_COMMAND:$^X-MExtUtils::Typemaps::Cmd
                     -e"print embeddable_typemap(q{Basic})"

Écriture des entrées de typemap

Chaque entrée de typemap INPUT ou OUTPUT est une chaîne Perl doublement citée qui sera évaluée en présence de certaines variables pour obtenir le code C final permettant de mapper un certain type C.

Cela signifie que vous pouvez intégrer du code Perl dans votre code typemap (C) en utilisant des constructions telles que ${ perl code that evaluates to scalar reference here }. Un cas d'utilisation commun est de générer des messages d'erreur qui font référence au vrai nom de la fonction, même en utilisant la fonctionnalité ALIAS XS :

${$ALIAS?q[GvNAME(CvGV(cv))]:qq["$pname"]}

Pour de nombreux exemples de typemap, reportez-vous au fichier typemap de base qui se trouve dans l'arbre source de perl à l'adresse suivante . lib/ExtUtils/typemap.

Les variables Perl qui sont disponibles pour l'interpolation dans les cartes de type sont les suivantes :

  • $var - le nom de la variable d'entrée ou de sortie, par exemple RETVAL pour les valeurs de retour.

  • $type - le type C brut du paramètre, tout : remplacé par _. par exemple, pour un type de Foo::Bar, Type est Foo__Bar

  • $ntype - le type fourni avec * remplacé par Ptr. par exemple, pour un type de Foo*, $ntype est FooPtr

  • $arg - l'entrée de la pile, que le paramètre est en entrée ou en sortie, par exemple. ST(0)

  • $argoff - le décalage de la pile de l'argument, c'est-à-dire 0 pour le premier argument, etc.

  • $pname - le nom complet du XSUB, y compris le nom de l'utilisateur. PACKAGE nom, avec toute PREFIX dépouillé. Il s'agit du nom non-ALIAS.

  • $Package - le paquet spécifié par le plus récent PACKAGE mot-clé.

  • $ALIAS - non nul si le XSUB actuel a des alias déclarés avec le mot clé ALIAS.

Liste complète des cartes types du noyau

Chaque type C est représenté par une entrée dans le fichier typemap qui est responsable de la conversion des variables perl (SV, AV, HV, CV, etc.) vers et depuis ce type. Les sections suivantes listent tous les types XS qui sont livrés avec perl par défaut.

T_SV

Cela passe simplement la représentation C de la variable Perl (un SV*) dans et hors de la couche XS. Cela peut être utilisé si le code C veut traiter directement avec la variable Perl.

T_SVREF

Utilisé pour passer et retourner une référence à un SV.

Notez que cette typologie ne décrémente pas le compte de référence lors du retour de la référence à un SV*. Voir aussi : T_SVREF_REFCOUNT_FIXED

T_SVREF_FIXED

Utilisé pour passer et retourner une référence à un SV. Il s'agit d'une variante fixe de T_SVREF qui décrémente le refcount de manière appropriée lors du retour d'une référence à un SV*. Introduit dans perl 5.15.4.

T_AVREF

Au niveau perl, il s'agit d'une référence à un tableau perl. Au niveau C, il s'agit d'un pointeur vers un AV.

Notez que ce typemap ne décrémente pas le compte de référence lors du retour d'un AV*. Voir aussi : T_AVREF_REFCOUNT_FIXED.

T_AVREF_REFCOUNT_FIXED

Du niveau perl, ceci est une référence à un tableau perl. Au niveau C, il s'agit d'un pointeur vers un AV. Il s'agit d'une variante fixe de T_AVREF qui décrémente le refcount de manière appropriée lorsqu'elle renvoie un AV*. Introduit dans perl 5.15.4.

T_HVREF

Du niveau perl, il s'agit d'une référence à un hachage perl. Au niveau C, il s'agit d'un pointeur vers un HV.

Notez que ce typemap ne décrémente pas le compte de référence lors du retour d'un HV*. Voir aussi : T_HVREF_REFCOUNT_FIXED.

T_HVREF_REFCOUNT_FIXED

Du niveau perl, il s'agit d'une référence à un hachage perl. Du niveau C, il s'agit d'un pointeur vers un HV. Il s'agit d'une variante fixe de T_HVREF qui décrémente le refcount de manière appropriée lorsqu'elle renvoie un HV*. Introduit dans perl 5.15.4.

T_CVREF

Du niveau perl, c'est une référence à une sous-routine perl (par exemple, $sub = sub { 1 } ;). Du niveau C, il s'agit d'un pointeur vers un CV.

Notez que ce typemap ne décrémente pas le compte de référence lorsqu'il retourne un HV*. Voir également : T_HVREF_REFCOUNT_FIXED.

T_CVREF_REFCOUNT_FIXED

Du niveau perl, il s'agit d'une référence à une sous-routine perl (par exemple, $sub = sub { 1 } ;). Du niveau C, il s'agit d'un pointeur vers un CV.

C'est une variante fixe de T_HVREF qui décrémente le refcount de manière appropriée lorsqu'elle renvoie un HV*. Introduit dans perl 5.15.4.

T_SYSRET

La typologie T_SYSRET est utilisée pour traiter les valeurs de retour des appels système. Il n'est significatif que lors du passage de valeurs de C à perl (il n'y a pas de concept de passage d'une valeur de retour système de Perl à C).

Les appels système renvoient -1 en cas d'erreur (en définissant ERRNO avec la raison) et (généralement) 0 en cas de succès. Si la valeur de retour est -1, ce typemap renvoie. undef. Si la valeur de retour n'est pas -1, ce typemap traduit un 0 (perl false) en "0 mais vrai" (qui est perl true) ou renvoie la valeur elle-même, pour indiquer que la commande a réussi.

Le module POSIX fait un usage intensif de ce type.

T_UV

Un nombre entier non signé.

T_IV

Un nombre entier signé. Celui-ci est coulé dans le type d'entier requis lorsqu'il est transmis au C et converti en un IV lorsqu'il est renvoyé à Perl.

T_INT

Un nombre entier signé. Ce typage convertit la valeur Perl en un type entier natif (le type int sur la plate-forme actuelle). Lors du retour de la valeur à perl, elle est traitée de la même manière que pour T_IV.

Son comportement est identique à l'utilisation d'un type int en XS avec T_IV.

T_ENUM

Une valeur d'enum. Utilisé pour transférer un composant d'enum depuis C. Il n'y a aucune raison de passer une valeur d'enum à C puisqu'elle est stockée comme un IV à l'intérieur de perl.

T_BOOL

Un type booléen. Cela peut être utilisé pour passer des valeurs vraies et fausses vers et depuis C.

T_U_INT

Ceci est pour les entiers non signés. Il est équivalent à l'utilisation de T_UV mais caste explicitement la variable au type. unsigned int. Le type par défaut de unsigned int est T_UV.

T_SHORT

Entiers courts. Ceci est équivalent à T_IV mais caste explicitement le retour au type short. La carte de type par défaut pour short est T_IV.

T_U_SHORT

Entiers courts non signés. Ceci est équivalent à T_UV mais caste explicitement le retour au type unsigned short. La carte de type par défaut pour unsigned short est T_UV.

T_U_SHORT est utilisé pour le type U16 dans la carte de type standard.

T_LONG

Les entiers longs. Ceci est équivalent à T_IV mais caste explicitement le retour au type long. La carte de type par défaut pour long est T_IV.

T_U_LONG

Entiers longs non signés. Ceci est équivalent à T_UV mais caste explicitement le retour au type unsigned long. La carte de type par défaut pour unsigned long est T_UV.

T_U_LONG est utilisé pour le type U32 dans la carte de type standard.

T_CHAR

Caractères simples de 8 bits.

T_U_CHAR

Un octet non signé.

T_FLOAT

Un nombre à virgule flottante. Cette typologie garantit le retour d'une variable coulée vers un float.

T_NV

Un nombre à virgule flottante Perl. Similaire à T_IV et T_UV en ce que le type de retour est coulé vers le type numérique demandé plutôt que vers un type spécifique.

T_DOUBLE

Un nombre à virgule flottante de double précision. Cette typologie garantit le retour d'une variable coulée vers un type numérique. double.

T_PV

Une chaîne de caractères (char *).

T_PTR

Une adresse mémoire (pointeur). Généralement associé à un void * type.

T_PTRREF

Similaire à T_PTR sauf que le pointeur est stocké dans un scalaire et la référence à ce scalaire est retournée à l'appelant. Ceci peut être utilisé pour cacher la valeur réelle du pointeur au programmeur puisqu'elle n'est généralement pas requise directement depuis perl.

Le typemap vérifie qu'une référence scalaire est passée de perl à XS.

T_PTROBJ

Similaire à T_PTRREF sauf que la référence est bénie dans une classe. Cela permet au pointeur d'être utilisé comme un objet. Le plus souvent utilisé pour traiter les structs C. Le typemap vérifie que l'objet perl passé dans la routine XS est de la bonne classe (ou fait partie d'une sous-classe).

Le pointeur est béni dans une classe qui est dérivée du nom du type du pointeur mais avec tous les '*' dans le nom remplacés par 'Ptr'.

Pour DESTROY XSUBs seulement, un T_PTROBJ est optimisé en un T_PTRREF. Cela signifie que la vérification de la classe est sautée.

T_REF_IV_REF

NOT YET

T_REF_IV_PTR

Similaire à T_PTROBJ dans le sens où le pointeur est béni en un objet scalaire. La différence est que lorsque l'objet est repassé dans XS, il doit être du bon type (l'héritage n'est pas supporté) alors que T_PTROBJ supporte l'héritage.

Le pointeur est béni dans une classe qui est dérivée du nom du type du pointeur mais avec tous les '*' dans le nom remplacés par 'Ptr'.

Pour DESTROY XSUBs seulement, un T_REF_IV_PTR est optimisé en un T_PTRREF. Cela signifie que la vérification de la classe est sautée.

T_PTRDESC

PAS ENCORE

T_REFREF

Similaire à T_PTRREF, sauf que le pointeur stocké dans le scalaire référencé est déréférencé et copié dans la variable de sortie. Cela signifie que T_REFREF est à T_PTRREF ce que T_OPAQUE est à T_OPAQUEPTR. Tout est clair ?

Seule la partie INPUT de ceci est implémentée (Perl à XSUB) et il n'y a aucun utilisateur connu dans le noyau ou sur CPAN.

T_REFOBJ

Comme T_REFREF, sauf qu'il fait une vérification stricte des types (l'héritage n'est pas supporté).

Pour DESTROY XSUBs seulement, un T_REFOBJ est optimisé en un T_REFREF. Cela signifie que la vérification de classe est sautée.

T_OPAQUEPTR

Ceci peut être utilisé pour stocker des octets dans la composante chaîne de caractères de la SV. Ici, la représentation des données n'est pas pertinente pour perl et les octets eux-mêmes sont juste stockés dans le SV. Il est supposé que la variable C est un pointeur (les octets sont copiés à partir de cet emplacement mémoire). Si le pointeur pointe sur quelque chose qui est représenté par 8 octets, alors ces 8 octets sont stockés dans le SV (et length() rapportera une valeur de 8). Cette entrée est similaire à T_OPAQUE.

En principe, la commande unpack() peut être utilisée pour reconvertir les octets en un nombre (si le type sous-jacent est connu pour être un nombre).

Cette entrée peut être utilisée pour stocker une structure C (le nombre d'octets à copier est calculé à l'aide de la commande C. sizeof ) et peut être utilisée comme une alternative à T_PTRREF sans avoir à se soucier d'une fuite de mémoire (puisque Perl nettoiera le SV).

T_OPAQUE

Ceci peut être utilisé pour stocker des données de types non pointeurs dans la partie chaîne de caractères d'un SV. Il est similaire à T_OPAQUEPTR sauf que le typemap récupère directement le pointeur plutôt que de supposer qu'il est fourni. Par exemple, si un entier est importé en Perl en utilisant T_OPAQUE plutôt que T_IV, les octets sous-jacents représentant l'entier seront stockés dans le SV mais la valeur réelle de l'entier ne sera pas disponible. c'est-à-dire que les données sont opaques pour perl.

Les données peuvent être récupérées en utilisant la fonction unpack si le type sous-jacent du flux d'octets est connu.

T_OPAQUE supporte l'entrée et la sortie de types simples. T_OPAQUEPTR peut être utilisé pour repasser ces octets en C si un pointeur est acceptable.

Tableau implicite

xsubpp supporte une syntaxe spéciale pour retourner des tableaux C empaquetés à perl. Si le type de retour XS est donné comme

array(type, nelem)

xsubpp copiera le contenu de nelem * sizeof(type) octets de RETVAL vers un SV et le poussera sur la pile. Ceci n'est vraiment utile que si le nombre d'éléments à retourner est connu au moment de la compilation et que cela ne vous dérange pas d'avoir une chaîne d'octets dans votre SV. Utilisez T_ARRAY pour pousser un nombre variable d'arguments sur la pile de retour (ils ne seront pas emballés comme une seule chaîne de caractères cependant).

Ceci est similaire à l'utilisation de T_OPAQUEPTR mais peut être utilisé pour traiter plus d'un élément.

T_PACKED

Appelle des fonctions fournies par l'utilisateur pour la conversion. Pour OUTPUT (XSUB vers Perl), une fonction nommée XS_pack_$ntype est appelée avec le scalaire Perl de sortie et la variable C à convertir. $ntype est le type C normalisé qui doit être converti en Perl. Normalisé signifie que toutes les variables * sont remplacés par la chaîne Ptr. La valeur de retour de la fonction est ignorée.

Inversement, pour INPUT (Perl vers XSUB), la fonction nommée XS_unpack_$ntype est appelé avec le scalaire Perl d'entrée comme argument et la valeur de retour est coulée dans le type C mappé et assignée à la variable C de sortie.

Un exemple de fonction de conversion pour un struct typemapped. foo_t * pourrait être :

static void
XS_pack_foo_tPtr(SV *out, foo_t *in){
  dTHX;/* alas, signature does not include pTHX_ */
  HV* hash = newHV();
  hv_stores(hash,"int_member", newSViv(in->int_member));
  hv_stores(hash,"float_member", newSVnv(in->float_member));/* ... *//* mortalize as thy stack is not refcounted */
  sv_setsv(out, sv_2mortal(newRV_noinc((SV*)hash)));}

La conversion de Perl en C est laissée comme un exercice au lecteur, mais le prototype serait :

static foo_t *
XS_unpack_foo_tPtr(SV *in);

Au lieu d'une fonction C réelle qui doit aller chercher le contexte du thread en utilisant dTHXvous pouvez définir des macros du même nom et éviter l'overhead. N'oubliez pas non plus de libérer éventuellement la mémoire allouée par la fonction XS_unpack_foo_tPtr.

T_PACKEDARRAY

T_PACKEDARRAY est similaire à T_PACKED. En effet, le INPUT (de Perl à XSUB) est identique, mais la carte de type OUTPUT passe un argument supplémentaire à la fonction XS_pack_$ntype un argument supplémentaire. Ce troisième paramètre indique le nombre d'éléments dans la sortie afin que la fonction puisse gérer sainement les tableaux C. La variable doit être déclarée par l'utilisateur et doit porter le nom. count_$ntype$ntype est le nom du type C normalisé comme expliqué ci-dessus. La signature de la fonction serait, pour l'exemple ci-dessus, et foo_t **:

static void
XS_pack_foo_tPtrPtr(SV *out, foo_t *in, UV count_foo_tPtrPtr);

Le type du troisième paramètre est arbitraire en ce qui concerne la carte des types. Il doit juste être en accord avec la variable déclarée.

Bien sûr, à moins que vous ne connaissiez le nombre d'éléments de la fonction sometype ** C array, à l'intérieur de votre XSUB, la valeur de retour de la fonction foo_t ** XS_unpack_foo_tPtrPtr(...) sera difficile à déchiffrer. Puisque les détails sont tous à la charge de l'auteur XS (l'utilisateur de la carte de type), il existe plusieurs solutions, dont aucune n'est particulièrement élégante. La solution la plus courante a été d'allouer de la mémoire pour les pointeurs N+1 et d'assigner à la fonction NULL au (N+1)ème pour faciliter l'itération.

Alternativement, l'utilisation d'une carte de type personnalisée pour vos objectifs en premier lieu est probablement préférable.

T_DATAUNIT

PAS ENCORE

T_CALLBACK

PAS ENCORE

T_ARRAY

Ceci est utilisé pour convertir la liste d'arguments perl en un tableau C et pour pousser le contenu d'un tableau C sur la pile d'arguments perl.

La signature d'appel habituelle est

@out= array_func(@in);

Un nombre quelconque d'arguments peut apparaître dans la liste avant le tableau, mais les tableaux d'entrée et de sortie doivent être les derniers éléments de la liste.

Lorsqu'il est utilisé pour passer une liste perl à C, le rédacteur XS doit fournir une fonction (nommée d'après le type de tableau mais avec 'Ptr' substitué à '*') pour allouer la mémoire nécessaire pour contenir la liste. Un pointeur doit être retourné. C'est au rédacteur XS de libérer la mémoire à la sortie de la fonction. La variable ix_$var est fixée au nombre d'éléments du nouveau tableau.

Lorsqu'il retourne un tableau C à Perl, le rédacteur XS doit fournir une variable entière appelée size_$var contenant le nombre d'éléments dans le tableau. Ceci est utilisé pour déterminer combien d'éléments doivent être poussés sur la pile d'arguments de retour. Ceci n'est pas nécessaire en entrée puisque Perl sait combien d'arguments sont sur la pile lorsque la routine est appelée. Ordinairement, cette variable serait appelée size_RETVAL.

De plus, le type de chaque élément est déterminé à partir du type du tableau. Si le tableau utilise le type intArray * xsubpp déterminera automatiquement qu'il contient des variables de type int et utilisera cette entrée de carte de type pour effectuer la copie de chaque élément. Tous les pointeurs '*' et les balises 'Array' sont supprimés du nom pour déterminer le sous-type.

T_STDIO

Ceci est utilisé pour passer les filehandles perl vers et depuis le C en utilisant le langage FILE * structures.

T_INOUT

Ceci est utilisé pour passer des filehandles perl vers et depuis C en utilisant PerlIO * structures. Le handle de fichier peut être utilisé pour la lecture et l'écriture. Cela correspond à la structure +< voir également T_IN et T_OUT.

Voir perliol pour plus d'informations sur la couche d'abstraction IO de Perl. Perl doit avoir été construit avec -Duseperlio.

Il n'y a pas de vérification pour affirmer que le filehandle passé de Perl à C a été créé avec la bonne... open() mode.

Astuce : le tutoriel perlxstut couvre bien les types XS T_INOUT, T_IN et T_OUT.

T_IN

Identique à T_INOUT, mais le filehandle qui est retourné de C à Perl ne peut être utilisé que pour la lecture (mode <).

T_OUT

Identique à T_INOUT, mais le fichier retourné par C à Perl est configuré pour utiliser le mode ouvert. +>.