wiki:InsiaProgPerlC

Sommaire

Programmation Perl - Intégration avec les autres langages (XS)

Références:

1. Coopérer avec les autres langages

Interopérabilité

Perl est un langage dont l'interpréteur est écrit en C, il jouit ainsi de l'universalité et de la portabilité de ce langage. Perl est disponible sur à peu près toutes les plateformes matérielles et logicielles disponibles, de DOS à Unix en passant par Amiga, VMS, etc.

Mais son implémentation lui confère un autre avantage: le langage C reste encore la base commune la plus large et la plus solide pour la communication entre les langages. Un langage de haut niveau se doit en particulier de fournir une interface simple et efficace pour réutiliser tout ce qui a été produit en C, c'est en particulier le cas de Python, Ruby, Tcl, Java, etc.

Il n'est pas rare de choisir un langage de haut niveau principalement pour sa capacité à s'interfacer avec des bibliothèques bas niveau existantes. Perl possède une interface universe via C appelée XS raisonnablement simple à utiliser.

Pertinence, performance

Si Perl est adapté pour résoudre certains problèmes, il ne l'est pas forcément à lui tout seul pour des problèmes trop complexes. Il n'est pas rare de réunir les atouts de plusieurs langages pour profiter des avantages de chacun d'eux.

Perl est typiquement rapide et efficace pour prototyper et réaliser du code logique de "haut niveau" (interfaces homme-machine, protocoles applicatifs, traitement simple d'information, etc). Mais par exemple dans le cas de calculs intensifs ou traitements de données numériques complexes, il est loin d'être aussi adapté que le C ou le Fortran. Il peut alors être simple et très efficace de déléguer uniquement les travaux pour lesquels Perl n'est pas adapté ou pas assez performant.

2. XS

Principe

XS désigne une suite d'outils et d'interfaces permettant d'étendre l'interpréteur Perl avec des bibliothèques existantes en C (ou langage "compatible" comme le C++). Le principe est le suivant:

  • vous possédez une interface C, normalement sous la forme d'un ou plusieurs fichiers .h contenant des prototypes de fonctions, ex:
    void  hello();
    int   somme(int a, int b);
    float moyenne(int nb, int* valeurs);
    
  • vous désirez produire une interface Perl équivalente. Perl n'ayant pas de prototypes de fonctions à proprement parler, nous imaginons que les fonctions se comporteraient comme si elles avaient été déclarées ainsi:
    sub hello   { ... };
    sub somme   { my($a, $b) = @_; ...; return $val; }
    sub moyenne { my(@valeurs) = @_; ...; return $val; }
    
  • vous voulez vous assurer que le passage de Perl à C (pour l'appel de la fonction), puis de C à Perl (retour de la fonction) se passe comme vous l'attendez
  • enfin vous voulez produire un module Perl qui se charge d'intégrer votre extension dans l'interpréteur de la manière la plus transparente possible, comme pour un module Perl: use MyModule;

h2xs

L'outil principal qui va nous aider à mener à bien cette tâche est h2xs. Comme son nom l'indique, il consomme des fichiers d'interface C (extension .h) et produit - entre autres - un fichier d'interfaçage .xs. Celui-ci ressemble beaucoup à un fichier C, mais avec des macros particulières:

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

#include "ppport.h"

MODULE = Hello   PACKAGE = Hello

void
hello()
  CODE:
    printf("Hello world !\n");

De fait, il peut être compilé via la procédure standard de distribution des modules Perl:

$ perl Makefile.PL
$ make

On obtient alors deux éléments:

  • un module Perl qui déclare les symboles (fonctions, variables, etc) fournis par le module natif
  • un module natif qui est une DLL qui sera chargée dynamiquement et étendra l'interpréteur Perl au moment où le module sera utilisé par le programme

3. In bed with Perl

Vous êtes en train de réaliser un programme en C (ou tout autre langage barbare), et vous réalisez que votre votre magnifique parseur écrit dans la sueur en 1000 lignes de code pourrait s'écrire en 10 lignes de perl avec 10 fois moins de bugs et probablement les mêmes performances, sans compter la facilité de maintenance qui consiste à modifier un petit fichier texte sans le recompiler.

Ce rêve est réalisable: vous pouvez embarquer (embedded en anglais) un interpréteur Perl dans votre programme et faire appel à lui dès que vous en ressentez l'envie. Bien entendu cet interpréteur n'aura accès qu'aux détails internes de votre programme que vous voudrez bien lui présenter, et il reste un élément relativement indépendant mais qui peut travailler de façon très étroite avec votre programme.

Exemple:

...
STRLEN n_a;
SV *val = eval_pv("reverse lc ’rekcaH lreP rehtonA tsuJ’", TRUE);
printf("Lower-case reverse is '%s' (thanks to Perl)\n", SvPV(val,n_a));
...

4. Perl sans Perl

Dans une certaine mesure, il est possible de transformer un programme Perl en un programme C natif. Il exist un outil (perlcc) capable de transformer l'expression d'un programme en Perl en un programme C, puis de compiler ce dernier. Ceci est considéré expérimental, et nécessite d'embarquer de lourdes bibliothèques Perl avec le programme: on obtient ainsi des binaires lourds et sans gain de performance notable.

Notez que le même outil perlcc peut produire une version binaire intermédiaire de type bytecode, ce qui donc ne vous dispense pas de l'interpréteur pour exécuter ce format de programme.

Last modified 13 years ago Last modified on Jun 3, 2007, 12:06:35 AM