POD2-FR

 view release on metacpan or  search on metacpan

FR/perlxs.pod  view on Meta::CPAN

       double x

Lorsqu'on utilise des pointeurs C, l'opérateur d'indirection C<*>
devrait être considéré comme une partie du type et l'opérateur
d'addressage C<&> comme une partie de la variable, comme on l'a fait
dans la fonction rpcb_gettime() ci-dessus. Consultez la section sur
les typemaps pour avoir plus de détails sur l'utilisation des
qualificateurs 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.

  INCORRECT                        CORRECT

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

Le corps de la fonction peut être mis en retrait ou ajusté à
gauche. L'exemple suivant montre une fonction dont le corps est ajusté
à gauche. On utilisera un retrait dans la plupart des exemples de ce
document.

  CORRECT

  double
  sin(x)
  double 

=head2 La pile des arguments

La pile des arguments est utilisée pour stocker les valeurs qui sont
envoyées à la XSUB en tant que paramètres, ainsi que la valeur de
retour de la XSUB. En fait, toutes les fonctions Perl mettent leurs
valeurs sur cette pile en même temps, chacune étant limitée à son
propre intervalle de positions sur la pile. Dans ce document, la
première position dans la pile appartenant à la fonction active sera
désignée comme la position 0 pour cette fonction.

Les XSUB se réfèrent à leurs arguments de la pile avec la macro
B<ST(x)>, où I<x> désigne une position dans l'intervalle appartenant à
la XSUB sur la pile. La position 0 pour cette fonction est connue de
la XSUB comme ST(0). Les paramètres en entrée et les valeurs de retour
de la XSUB commencent toujours à ST(0). Dans de nombreux cas simples,
le compilateur B<xsubpp> générera le code nécessaire à la manipulation
de la pile des arguments en insérant des morceaux de code trouvés dans
les typemaps. Dans les cas plus complexes, le programmeur devra
fournir le code.

=head2 La variable RETVAL

La variable RETVAL est une variable magique qui est toujours du type
retourné par la fonction de la librairie C. Le compilateur B<xsubpp>
fournit cette variable dans chaque XSUB et l'utilise par défaut pour y
mettre la valeur de retour de la fonction C appelée. Dans les cas
simples, la valeur de RETVAL sera mise dans ST(0) sur la pile
d'arguments, où Perl le recevra comme valeur de retour de la XSUB.

Si la XSUB a un type de retour égal à C<void>, le compilateur ne
fournira pas de variable RETVAL pour cette fonction. Lorsqu'on utilise
la directive PPCODE:, la variable RETVAL n'est plus nécessaire, sauf
si on l'utilise explicitement.

Si la directive PPCODE: n'est pas utilisée, la valeur de retour
C<void> devrait être utilisée uniquement pour des sous-routines qui ne
renvoient pas de valeur, I<même si> la directive CODE: est utilisée
pour positionner ST(0) explicitement.

Dans des versions plus anciennes de ce document, on conseillait
d'utiliser la valeur de retour C<void> dans de tels cas. On a
découvert que cela pouvait mener à des segfaults lorsque la XSUB était
I<vraiment> C<void>. Cette pratique est maintenant désapprouvée, et
risque de ne plus être supportée dans une version future. Utilisez la
valeur de retour C<SV *> dans ces cas-là (C<xsubpp> contient
actuellement du code heuristique qui tente de faire la différence
entre les fonctions "vraiment-void" et celles qui sont
"déclarées-void-suivant-l'ancienne-pratique" ; votre code est donc à
la merci de l'heuristique si vous n'utilisez pas C<SV *> comme valeur
de retour).

=head2 Le mot-clé MODULE

Le mot-clé MODULE est utilisé pour marquer le début du code XS et
spécifier un paquetage pour les fonctions que l'on est en train de
définir. Tout le texte qui précède le premier mot-clé MODULE est
considéré comme du code C et sera transféré dans la sortie du
compilateur sans modification. Tout module XS aura une fonction
d'initialisation utilisée pour brancher la XSUB dans Perl. Le nom du
paquetage de cette fonction d'initialisation correspondra à la valeur
de la dernière instruction MODULE dans les fichiers source XS. La
valeur de MODULE devrait toujours rester constante à l'intérieur d'un
même fichier XS, même si cela n'est pas obligatoire.

L'exemple suivant démarre le code XS et place toutes les fonctions
dans un paquetage nommé RPC.

     MODULE = RPC

=head2 Le mot-clé PACKAGE

Lorsque les fonctions, à l'intérieur d'un fichier source XS, doivent
être réparties dans des paquetages, il faut utiliser le mot-clé
PACKAGE. Ce mot-clé est utilisé avec le mot-clé MODULE et doit être
spécifié immédiatement après lui.

     MODULE = RPC  PACKAGE = RPC

     [ code XS dans le paquetage RPC ]

     MODULE = RPC  PACKAGE = RPCB

     [ code XS dans le paquetage RPCB ]

     MODULE = RPC  PACKAGE = RPC

     [ code XS dans le paquetage RPC ]

Bien que ce mot-clé soit optionnel et qu'il fournisse des informations
redondantes dans certains cas, il devrait toujours être utilisé. Il
permet de garantir que la XSUB apparaîtra dans le paquetage désiré.

=head2 Le mot-clé PREFIX

Le mot-clé PREFIX désigne des préfixes à supprimer dans les noms de

FR/perlxs.pod  view on Meta::CPAN

Dans cet autre exemple, chacun des paramètres en entrée voit son
évaluation retardée.

    bool_t
    rpcb_gettime(host,timep)
          PREINIT:
          time_t tt;
          INPUT:
          char *host
          PREINIT:
          char *h;
          INPUT: 
          time_t timep
          CODE:
               h = host;
               RETVAL = rpcb_gettime( h, &tt );
               timep = tt;
          OUTPUT:
          timep
          RETVAL

=head2 Listes de paramètres de longueur variable

Les XSUB peuvent recevoir des listes de paramètres de longueur
variable en spécifiant une ellipse C<...> dans la liste des
paramètres. Cette utilisation de l'ellipse est similaire à celle que
l'on trouve en C ANSI. Le programmeur peut déterminer le nombre
d'arguments passés à la XSUB en examinant la variable C<items> que le
compilateur B<xsubpp> fournit pour chaque XSUB. Grâce à ce mécanisme,
on peut réaliser une XSUB qui accepte une liste de paramètres de
longueur indéterminée.

Le paramètre I<host> de la XSUB rpcb_gettime() peut être optionnel, de
manière à ce qu'on puisse utiliser l'ellipse pour indiquer que la XSUB
prendra un nombre variable de paramètres. Perl devrait pouvoir appeler
cette XSUB avec chacune des instructions suivantes.

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

     $status = rpcb_gettime( $timep );

Voici le code XS, avec l'ellipse :

     bool_t
     rpcb_gettime(timep, ...)
          time_t timep = NO_INIT
          PREINIT:
          char *host = "localhost";
          CODE:
                  if( items > 1 )
                       host = (char *)SvPV(ST(1), PL_na);
                  RETVAL = rpcb_gettime( host, &timep );
          OUTPUT:
          timep
          RETVAL

=head2 Le mot-clé C_ARGS

Le mot-clé C_ARGS permet de réaliser des XSUB que l'on n'appelle pas
de la même manière depuis Perl que depuis C, sans qu'il soit
nécessaire d'écrire une section CODE: ou PPCODE:. Le contenu du
paragraphe C_ARGS est passé comme argument à la fonction C, sans aucun
changement.

Supposons par exemple que la fonction C soit déclarée ainsi :

    symbolic nth_derivative(int n, symbolic function, int flags);

et que la valeur par défaut de I<flags> soit contenue dans la variable
C I<default_flags>. Supposons que vous souhaitiez réaliser une
interface que l'on appellera de la manière suivante :

    $second_deriv = $function->nth_derivative(2);

Pour cela, déclarez la XSUB ainsi :

    symbolic
    nth_derivative(function, n)
        symbolic        function
        int             n
    C_ARGS:
        n, function, default_flags

=head2 Le mot-clé PPCODE

Le mot-clé PPCODE: est une variante du mot-clé CODE: qui est utilisée
pour indiquer au compilateur B<xsubpp> que le programmeur fournit le
code contrôlant la pile des arguments pour les valeurs de retour des
XSUB. On souhaite parfois que la XSUB renvoie une liste de valeurs et
non une valeur unique. Dans ce cas-là, il faut utiliser PPCODE: et
rajouter de manière explicite la liste des valeurs sur la pile. Les
mots-clés PPCODE: et CODE: ne sont pas utilisés simultanément dans la
même XSUB.

La XSUB suivante appelle la fonction C rpcb_gettime() et renvoie à Perl
ses deux valeurs de sortie, timep et status, comme une seule liste.

     void
     rpcb_gettime(host)
          char *host
          PREINIT:
          time_t  timep;
          bool_t  status;
          PPCODE:
          status = rpcb_gettime( host, &timep );
          EXTEND(SP, 2);
          PUSHs(sv_2mortal(newSViv(status)));
          PUSHs(sv_2mortal(newSViv(timep)));

Remarquez que le programmeur doit fournir le code C assurant l'appel
de la vraie fonction rpcb_gettime(), ainsi que le placement correct
des valeurs de retour sur la pile des arguments.

Le type de retour C<void> pour cette fonction indique au compilateur
B<xsubpp> que la variable RETVAL n'est pas nécessaire, qu'elle n'est
pas utlisée, et qu'elle ne devrait pas être créée. Dans la plupart des
cas, il faut utiliser le type de retour void avec l'instruction
PPCODE:.

On utilise la macro EXTEND() afin de dégager de la place sur la pile
des arguments pour les 2 valeurs de retour. L'instruction PPCODE: fait
en sorte que le compilateur B<xsubpp> crée un pointeur vers la pile
dans la variable C<SP> ; c'est ce pointeur qui est utilisé dans la
macro EXTEND(). Les valeurs sont ensuite rajoutées sur la pile avec
les macros PUSHs().

A présent, la fonction rpcb_gettime() peut être utilisée depuis Perl
avec l'instruction suivante.

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

Lorsque vous travaillez sur les paramètres en sortie avec une section
PPCODE:, assurez-vous de traiter l'effet 'set'
convenablement. Consultez L<perlguts> pour plus de détails sur cet
effet 'set'.

=head2 Renvoyer undef et des listes vides

Le programmeur voudra parfois renvoyer simplement C<undef> ou une
liste vide si la fonction échoue, plutôt qu'une valeur d'état à
part. La fonction rpcb_gettime() présente justement cette
situation. Nous aimerions que la fonction retourne l'heure si elle
réussit, ou undef si elle échoue. Dans le code Perl suivant, la valeur
de $timep sera soit undef, soit une heure valide;

     $timep = rpcb_gettime( "localhost" );

La XSUB suivante n'utilise le type de retour C<SV *> qu'à titre
d'aide-mémoire, et il utilise un bloc CODE: pour indiquer au
compilateur que le programmeur a fourni tout le code
nécessaire. L'appel de sv_newmortal() initialise la valeur de retour à
undef, ce qui en fait la valeur de retour par défaut.

     SV *
     rpcb_gettime(host)
          char *  host
          PREINIT:
          time_t  timep;
          bool_t x;
          CODE:
          ST(0) = sv_newmortal();
          if( rpcb_gettime( host, &timep ) )
               sv_setnv( ST(0), (double)timep);

Cet autre exemple montre comment on peut mettre un undef explicite
dans la valeur de retour, au cas où le besoin s'en ferait ressentir.

     SV *
     rpcb_gettime(host)
          char *  host
          PREINIT:
          time_t  timep;
          bool_t x;
          CODE:
          ST(0) = sv_newmortal();
          if( rpcb_gettime( host, &timep ) ){
               sv_setnv( ST(0), (double)timep);
          }
          else{
               ST(0) = &PL_sv_undef;
          }

Pour renvoyer une liste vide, il faut utiliser un bloc PPCODE: et ne
pas rajouter de valeur de retour sur la pile.

     void
     rpcb_gettime(host)
          char *host
          PREINIT:
          time_t  timep;
          PPCODE:
          if( rpcb_gettime( host, &timep ) )
               PUSHs(sv_2mortal(newSViv(timep)));
          else{
          /* Rien n'est remis sur la pile, donc une */
          /* liste vide est renvoyee implicitement */
          }

Certaines personnes préfèrent rajouter un C<return> explicite dans la
XSUB ci-dessus au lieu de laisser l'exécution se poursuivre jusqu'au
bout. Dans ce cas-là, il convient plutôt d'utiliser C<XSRETURN_EMPTY>,
ce qui garantira que la pile XSUB est ajustée correctement. D'autres
macros sont décrites dans L<perlguts>.

=head2 Le mot-clé REQUIRE

Le mot-clé REQUIRE: sert à indiquer le numéro de version minimal du
compilateur B<xsubpp> requis pour compiler le module XS. Un module XS
contenant l'instruction suivante ne pourra être compilé qu'avec une
version de B<xsubpp> égale ou supérieure à 1.922 :

        REQUIRE: 1.922

=head2 Le mot-clé CLEANUP

Ce mot-clé peut être utilisé quand une XSUB doit exécuter des
procédures de nettoyage spéciales avant de se terminer. Quand le
mot-clé CLEANUP: est utilisé, il doit suivre tout bloc CODE:, PPCODE:
ou OUTPUT: présent dans la XSUB. Les instructions spécifiées dans le bloc de
nettoyage seront les dernières instructions de la XSUB.

=head2 Le mot-clé BOOT

Le mot-clé BOOT: permet de rajouter du code dans la fonction
d'amorçage de l'extension.  La fonction d'amorçage est générée par le
compilateur B<xsubpp> et contient normalement les instructions
nécessaires pour enregistrer toute XSUB auprès de Perl. Avec le
mot-clé BOOT:, le programmeur peut dire au compilateur de rajouter des
instructions supplémentaires dans la fonction d'amorçage.

Ce mot-clé peut être utilisé n'importe quand après le premier mot-clé
MODULE, et doit être tout seul sur une ligne. La première ligne
blanche après le mot-clé terminera le bloc de code.

     BOOT:
     # Le message suivant sera affiche lors de l'execution de la
     # fonction d'amorcage.
     printf("bonjour !\n");

=head2 Le mot-clé VERSIONCHECK

Le mot-clé VERSIONCHECK: correspond aux options C<-versioncheck> et
C<-noversioncheck> de B<xsubpp>. Ce mot-clé prime sur les options de
la ligne de commande. La vérification de version est activée par
défaut. Lorsqu'elle est activée, le module XS essaie de vérifier que
son numéro de version est compatible avec celui du module PM.

Pour activer la vérification de version :

    VERSIONCHECK: ENABLE

Pour la désactiver :

    VERSIONCHECK: DISABLE

=head2 Le mot-clé PROTOTYPES

Le mot-clé PROTOTYPES: correspond aux options C<-prototypes> et
C<-noprototypes> de B<xsubpp>. Ce mot-clé prime sur les options de la
ligne de commande. Les prototypes sont activés par défaut. Lorsqu'ils
sont activés, les XSUB reçoivent des prototypes Perl. Ce mot-clé peut
être utilisé plusieurs fois dans un module XS pour activer et
désactiver les prototypes dans différentes parties du module.

Pour activer les prototypes :

    PROTOTYPES: ENABLE

Pour les désactiver :

    PROTOTYPES: DISABLE

=head2 Le mot-clé PROTOTYPE

Ce mot-clé est proche du mot-clé PROTOTYPES: ci-dessus, mais peut être
utilisé pour forcer B<xsubpp> à utiliser un prototype donné pour la
XSUB. Ce mot-clé prime sur toute autre option ou mot-clé relatif au
prototypage, mais n'affecte que la XSUB courante. Consultez

FR/perlxs.pod  view on Meta::CPAN

          INPUT:
          # 'a' est timep, 'b' est host
          char *b
          time_t a = NO_INIT
          CODE:
               RETVAL = rpcb_gettime( b, &a );
          OUTPUT:
          a
          RETVAL
      CASE:
          # 'a' est host, 'b' est timep
          char *a
          time_t &b = NO_INIT
          OUTPUT:
          b
          RETVAL

Cette fonction peut être appelée avec chacune des instructions
suivantes. Notez la différence dans l'ordre des arguments.

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

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

=head2 L'opérateur unaire &

L'opérateur unaire & est utilisé pour dire au compilateur qu'il doit
déréférencer l'objet lors de l'appel à la fonction C. On utilise ce
procédé lorsqu'on n'a pas mis de bloc CODE: et que l'objet n'est pas
de type pointeur (l'objet est un C<int> ou un C<long>, mais pas un
C<int*> ni un C<long*>).

La XSUB suivante génère du code C incorrect. Le code généré par
B<xsubpp> appellera C<rpcb_gettime()> avec les paramètres C<(char
*host, time_t timep)>, mais le vrai C<rpcb_gettime()> attend un
paramètre C<timep> de type C<time_t *> et non C<time_t>.

    bool_t
    rpcb_gettime(host,timep)
          char *host
          time_t timep
          OUTPUT:
          timep

On résout ce problème en utilisant l'opérateur C<&>. Le compilateur
B<xsubpp>, à présent, traduira la XSUB en code qui appellera
C<rpcb_gettime()> de manière correcte, avec les paramètres C<(char
*host, time_t *timep)>. Il le fait en conservant le C<&> tel quel, de
sorte que l'appel de fonction est C<rpcb_gettime(host, &timep)>.

    bool_t
    rpcb_gettime(host,timep)
          char *host
          time_t &timep
          OUTPUT:
          timep

=head2 Insérer des commentaires et des directives de pré-processeur C

Des directives de pré-processeur C peuvent prendre place à l'intérieur
des blocs BOOT:, PREINIT:, INIT:, CODE:, PPCODE: et CLEANUP:, de même
qu'en dehors des fonctions. Les commentaires sont autorisés partout
après le mot-clé MODULE. Le compilateur transmet les directives de
pré-processeur sans modification et supprime les lignes commentées.

On peut rajouter des commentaires dans les XSUB en mettant un C<#> sur
une ligne comme premier caractère non blanc. Attention, le commentaire
ne doit pas ressembler à une directive de pré-processeur C, sinon il
sera interprété comme tel. Le moyen le plus simple d'éviter cela
consiste à mettre des caractères blancs devant le C<#>.

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

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

et non pas

    #if ... version1
    #endif
    #if ... version2
    #endif

car, dans le second cas, xsubpp croira que vous avez défini la
fonction deux fois. Par ailleurs, insérez une ligne blanche avant le
C<#else> et le C<#endif> afin qu'ils ne soient pas considérés comme une
partie intégrante du corps de la fonction.

=head2 Utiliser XS avec C++

Si une fonction est définie comme une méthode C++, alors elle
considère son premier argument comme un pointeur vers un objet. Le
pointeur vers l'objet est stocké dans une variable nommée
THIS. L'objet doit avoir été créé en C++ avec la fonction new(), et il
doit être béni par Perl (comme avec la fonction bless() en Perl pur)
avec la macro sv_setref_pv(). La I<bénédiction> d'un objet par Perl
peut être effectuée par le typemap. Un exemple de typemap est donné à
la fin de cette section.

Si la méthode est définie comme statique, elle appellera la fonction C++
en utilisant la syntaxe classe::methode(). Si la méthode n'est pas
statique, la fonction sera appelée avec la syntaxe THIS-E<gt>method().

Les exemples qui suivent utiliseront la classe C++ que voici :

     class color {
          public:
          color();
          ~color();
          int blue();
          void set_blue( int );

          private:
          int c_blue;
     };

Les XSUB pour les méthodes blue() et set_blue() sont définies avec le
nom de la classe, mais le paramètre pour l'objet (THIS, ou "self") est
implicite et il n'est pas mentionné dans la liste.



( run in 1.753 second using v1.01-cache-2.11-cpan-5511b514fd6 )