InglésFrancésEspañol

icono de página de OnWorks

perlxs - Online en la nube

Ejecute perlxs en el proveedor de alojamiento gratuito OnWorks sobre Ubuntu Online, Fedora Online, emulador en línea de Windows o emulador en línea de MAC OS

Este es el comando perlxs que se puede ejecutar en el proveedor de alojamiento gratuito de OnWorks utilizando una de nuestras múltiples estaciones de trabajo en línea gratuitas, como Ubuntu Online, Fedora Online, emulador en línea de Windows o emulador en línea de MAC OS.

PROGRAMA:

NOMBRE


perlxs - manual de referencia del lenguaje XS

DESCRIPCIÓN


Introducción
XS es ​​un formato de archivo de descripción de interfaz que se utiliza para crear una interfaz de extensión entre
Perl y código C (o una biblioteca C) que se desea usar con Perl. La interfaz XS es
combinado con la biblioteca para crear una nueva biblioteca que luego puede ser dinámicamente
cargado o enlazado estáticamente en perl. La descripción de la interfaz XS está escrita en XS
idioma y es el componente principal de la interfaz de extensión de Perl.

Antes de escribir XS, lea la sección "AVISOS" a continuación.

An XSUB forma la unidad básica de la interfaz XS. Después de la compilación por el xsubpp
compilador, cada XSUB equivale a una definición de función C que proporcionará el pegamento entre
Convenciones de llamadas de Perl y convenciones de llamadas de C.

El código de pegamento extrae los argumentos de la pila de Perl, convierte estos valores de Perl a la
formatos esperados por una función C, llame a esta función C, transfiere los valores de retorno del
La función C vuelve a Perl. Los valores de retorno aquí pueden ser un valor de retorno C convencional o cualquier C
argumentos de función que pueden servir como parámetros de salida. Estos valores devueltos pueden pasarse
volver a Perl colocándolos en la pila de Perl o modificando los argumentos
suministrado desde el lado de Perl.

Lo anterior es una vista algo simplificada de lo que realmente sucede. Dado que Perl permite más
convenciones de llamadas flexibles que C, XSUB pueden hacer mucho más en la práctica, como verificar
parámetros de entrada para la validez, lanzando excepciones (o devolviendo undef / lista vacía) si el
El valor de retorno de la función C indica falla, llamando a diferentes funciones C basadas en
números y tipos de argumentos, proporcionando una interfaz orientada a objetos, etc.

Por supuesto, se podría escribir dicho código de pegamento directamente en C. Sin embargo, esto sería un tedioso
tarea, especialmente si uno necesita escribir pegamento para múltiples funciones C, y / o uno no es
lo suficientemente familiarizado con la disciplina de pila de Perl y otros arcanos similares. XS llega al
rescate aquí: en lugar de escribir este código C de pegamento a mano, uno puede escribir un más
taquigrafía concisa descripción de lo que debe hacer el pegamento, y deje que el compilador XS
xsubpp manejar el resto.

El lenguaje XS permite describir el mapeo entre cómo se usa la rutina C y
cómo se utiliza la rutina de Perl correspondiente. También permite la creación de rutinas Perl.
que se traducen directamente a código C y que no están relacionados con un C preexistente
función. En los casos en que la interfaz C coincide con la interfaz Perl, el XSUB
La declaración es casi idéntica a la declaración de una función C (en estilo K&R). De tal
circunstancias, hay otra herramienta llamada "h2xs" que es capaz de traducir una C completa
archivo de encabezado en un archivo XS correspondiente que proporcionará pegamento a las funciones / macros
descrito en el archivo de encabezado.

El compilador XS se llama xsubpp. Este compilador crea las construcciones necesarias para permitir
un XSUB manipula los valores de Perl y crea el pegamento necesario para permitir que Perl llame al XSUB.
El compilador usa mapas de tipos para determinar cómo mapear los parámetros de la función C y los valores de salida
a los valores de Perl y viceversa. El mapa de tipos predeterminado (que viene con Perl) maneja muchos
Tipos C. También puede ser necesario un mapa de tipos complementario para manejar cualquier estructura especial y
tipos para la biblioteca que se vincula. Para obtener más información sobre typemaps, consulte perlxstypemap.

Un archivo en formato XS comienza con una sección en lenguaje C que va hasta el primer "MODULE ="
directiva. Otras directivas XS y definiciones XSUB pueden seguir esta línea. El idioma"
utilizado en esta parte del archivo normalmente se conoce como el lenguaje XS. xsubpp
reconoce y omite POD (ver perlpod) en las secciones de lenguaje C y XS, que
permite que el archivo XS contenga documentación incrustada.

Consulte perlxstut para obtener un tutorial sobre todo el proceso de creación de extensiones.

Nota: Para algunas extensiones, el sistema SWIG de Dave Beazley puede proporcionar una
mecanismo conveniente para crear el código de pegamento de extensión. Verhttp://www.swig.org/> para
más información.

On El proyecto Carretera
Muchos de los ejemplos que siguen se concentrarán en la creación de una interfaz entre Perl
y las funciones de biblioteca de enlace ONC + RPC. los rpcb_gettime () la función se utiliza para
demostrar muchas características del lenguaje XS. Esta función tiene dos parámetros; el primero
es un parámetro de entrada y el segundo es un parámetro de salida. La función también devuelve un
valor de estado.

bool_t rpcb_gettime (const char * host, time_t * timep);

Desde C, esta función se llamará con las siguientes declaraciones.

#incluir
estado bool_t;
tiempo_t tiempop;
status = rpcb_gettime ("localhost", & timep);

Si se crea un XSUB para ofrecer una traducción directa entre esta función y Perl, entonces
este XSUB se utilizará desde Perl con el siguiente código. El $ status y $ timep
las variables contendrán la salida de la función.

utilizar RPC;
$ estado = rpcb_gettime ("localhost", $ timep);

El siguiente archivo XS muestra una subrutina XS, o XSUB, que demuestra una posible
interfaz a la rpcb_gettime () función. Este XSUB representa una traducción directa
entre C y Perl y, por lo tanto, conserva la interfaz incluso desde Perl. Este XSUB será
invocado desde Perl con el uso que se muestra arriba. Tenga en cuenta que los tres primeros #incluyen
declaraciones, para "EXTERN.h", "perl.h" y "XSUB.h", siempre estarán presentes en el
comienzo de un archivo XS. Este enfoque y otros se ampliarán más adelante en este
documento. Debe haber un #define para "PERL_NO_GET_CONTEXT" para buscar el intérprete
contexto de manera más eficiente, vea perlguts para más detalles.

#definir PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#incluir

MÓDULO = PAQUETE RPC = RPC

bool_t
rpcb_gettime (host, timep)
char * anfitrión
time_t & timep
SALIDA:
tiempop

Cualquier extensión de Perl, incluidas las que contienen XSUB, debe tener un módulo Perl para
sirven como el bootstrap que lleva la extensión a Perl. Este módulo exportará el
funciones y variables de la extensión al programa Perl y provocará que la extensión
XSUB que se vincularán a Perl. El siguiente módulo se utilizará para la mayoría de los ejemplos.
en este documento y debe usarse desde Perl con el comando "use" como se mostró anteriormente.
Los módulos de Perl se explican con más detalle más adelante en este documento.

paquete RPC;

requiera exportador;
requieren DynaLoader;
@ISA = qw (Exportador DynaLoader);
@EXPORTAR = qw (rpcb_gettime);

RPC de arranque;
1;

A lo largo de este documento, una variedad de interfaces para rpcb_gettime () XSUB será
explorado. Los XSUB tomarán sus parámetros en diferentes órdenes o tomarán diferentes
número de parámetros. En cada caso, el XSUB es una abstracción entre Perl y el real
C rpcb_gettime () función, y el XSUB siempre debe garantizar que el rpcb_gettime ()
se llama a la función con los parámetros correctos. Esta abstracción permitirá
programador para crear una interfaz más similar a Perl para la función C.

El proyecto Anatomía of an XSUB
Los XSUB más simples constan de 3 partes: una descripción del valor de retorno, el nombre del
Rutina XSUB y los nombres de sus argumentos, y una descripción de los tipos o formatos del
argumentos

El siguiente XSUB permite que un programa Perl acceda a una función de biblioteca C llamada sin ().
XSUB imitará la función C que toma un solo argumento y devuelve un solo valor.

doble
pecado (x)
doble X

Opcionalmente, se puede fusionar la descripción de tipos y la lista de nombres de argumentos,
reescribiendo esto como

doble
pecado (doble x)

Esto hace que este XSUB se parezca a una declaración ANSI C. Un punto y coma opcional es
permitido después de la lista de argumentos, como en

doble
sin (doble x);

Los parámetros con tipos de puntero C pueden tener diferentes semánticas: funciones C con similares
declaraciones

bool string_looks_as_a_number (char * s);
bool make_char_uppercase (char * c);

se utilizan de manera absolutamente incompatible. Los parámetros de estas funciones pueden ser
descrito xsubpp Me gusta esto:

carácter * s
char & c

Ambas declaraciones XS corresponden al tipo C "char *", pero tienen diferentes
semántica, consulte "El operador & Unary".

Es conveniente pensar que el operador de indirección "*" debe considerarse como una parte
del tipo y el operador de dirección "&" deben considerarse parte de la variable. Ver
perlxstypemap para obtener más información sobre el manejo de calificadores y operadores unarios en tipos C.

El nombre de la función y el tipo de retorno deben colocarse en líneas separadas y deben estar alineados
ajustado a la izquierda.

INCORRECTO CORRECTO

doble pecado (x) doble
doble x sin (x)
doble X

El resto de la descripción de la función se puede sangrar o ajustar a la izquierda. El seguimiento
El ejemplo muestra una función con su cuerpo ajustado a la izquierda. La mayoría de los ejemplos de este documento
sangra el cuerpo para una mejor legibilidad.

CORRECTA

doble
pecado (x)
doble X

Los XSUB más complicados pueden contener muchas otras secciones. Cada sección de un XSUB comienza
con la palabra clave correspondiente, como INIT: o CLEANUP :. Sin embargo, las dos primeras líneas
de un XSUB siempre contienen los mismos datos: descripciones del tipo de retorno y los nombres de
la función y sus parámetros. Todo lo que sigue inmediatamente a estos se considera
una sección INPUT: a menos que esté marcada explícitamente con otra palabra clave. (Ver "La ENTRADA:
Palabra clave".)

Una sección XSUB continúa hasta que se encuentra otra palabra clave de inicio de sección.

El proyecto Argumento Apilar
La pila de argumentos de Perl se utiliza para almacenar los valores que se envían como parámetros al
XSUB y para almacenar los valores de retorno de XSUB. En realidad, todas las funciones de Perl (incluidas
no XSUB) mantienen sus valores en esta pila al mismo tiempo, cada uno limitado a su propio
rango de posiciones en la pila. En este documento, la primera posición en esa pila que
pertenece a la función activa se denominará posición 0 para esa función.

Los XSUB se refieren a sus argumentos de pila con la macro ST (x), donde el x se refiere a una posición en
este XSUB es parte de la pila. La posición 0 para esa función sería conocida por el XSUB como
ST(0). Los parámetros entrantes y los valores devueltos salientes del XSUB siempre comienzan en ST(0).
Para muchos casos simples, el xsubpp El compilador generará el código necesario para manejar el
pila de argumentos incrustando fragmentos de código que se encuentran en los mapas de tipos. En casos más complejos
el programador debe proporcionar el código.

El proyecto RETVALO Variable
La variable RETVAL es una variable C especial que se declara automáticamente para usted. La C
type of RETVAL coincide con el tipo de retorno de la función de biblioteca C. los xsubpp compilador
declarará esta variable en cada XSUB con un tipo de retorno no "nulo". Por defecto el
La función C generada usará RETVAL para mantener el valor de retorno de la función de la biblioteca C
siendo llamado. En casos simples, el valor de RETVAL se colocará en ST(0) del argumento
stack donde puede ser recibido por Perl como el valor de retorno del XSUB.

Si el XSUB tiene un tipo de retorno de "void", el compilador no declarará un RETVAL
variable para esa función. Cuando se usa un PPCODE: sección sin manipulación del RETVAL
Se requiere una variable, la sección puede usar la manipulación directa de la pila para colocar los valores de salida.
en la pila

Si no se usa la directiva PPCODE:, el valor de retorno "void" debe usarse solo para subrutinas
que no devuelven un valor, even if CÓDIGO: se usa la directiva que establece ST(0) explícitamente.

Las versiones anteriores de este documento recomendaban utilizar un valor de retorno "nulo" en tales casos. Eso
se descubrió que esto podría conducir a segfaults en los casos en que XSUB fue verdaderamente "vacío". Esta
La práctica ahora está obsoleta y es posible que no se admita en alguna versión futura. Utilizar el
valor de retorno "SV *" en tales casos. (Actualmente, "xsubpp" contiene algún código heurístico que
intenta eliminar la ambigüedad entre las funciones "verdaderamente-vacío" y "práctica-antigua-declarada-como-nula".
Por lo tanto, su código está a merced de esta heurística a menos que use "SV *" como valor de retorno).

Volviendo SV, AV HV a través del programa RETVALO
Cuando usa RETVAL para devolver un "SV *", hay algo de magia detrás del
escenas que conviene mencionar. Cuando está manipulando la pila de argumentos usando el
En la macro ST (x), por ejemplo, normalmente debe prestar especial atención a los recuentos de referencias.
(Para obtener más información sobre los recuentos de referencias, consulte perlguts.) Para facilitarle la vida, el mapa de tipos
file automáticamente convierte a "RETVAL" en mortal cuando devuelve un "SV *". Por lo tanto, la
Los siguientes dos XSUB son más o menos equivalentes:

vacío
alfa()
CÓDIGOPP:
ST(0) = newSVpv ("Hola mundo", 0);
sv_2mortal (ST(0));
XSVOLVER(1);

VS *
beta()
CÓDIGO:
RETVAL = newSVpv ("Hola mundo", 0);
SALIDA:
RETVALO

Esto es bastante útil ya que generalmente mejora la legibilidad. Si bien esto funciona bien para un "SV
* ", lamentablemente no es tan fácil tener" AV * "o" HV * "como valor de retorno. should
ser capaz de escribir:

AV*
formación()
CÓDIGO:
RETVAL = newAV ();
/ * hacer algo con RETVAL * /
SALIDA:
RETVALO

Pero debido a un error que no se puede arreglar (arreglarlo rompería muchos módulos CPAN existentes) en el
archivo typemap, el recuento de referencias del "AV *" no se reduce correctamente. Por lo tanto, la
por encima de XSUB perderá memoria cada vez que se llame. El mismo problema existe para "HV
* "," CV * "y" SVREF "(que indica una referencia escalar, no un" SV * "general). En XS
código en perls a partir de perl 5.16, puede anular los mapas de tipos para cualquiera de estos
tipos con una versión que tiene un manejo adecuado de refcounts. En tu sección "TYPEMAP", haz

AV * T_AVREF_REFCOUNT_FIXED

para obtener la variante reparada. Para obtener compatibilidad con versiones anteriores de perl,
en su lugar, puede disminuir el recuento de referencias manualmente cuando devuelve uno de los
tipos antes mencionados usando "sv_2mortal":

AV*
formación()
CÓDIGO:
RETVAL = newAV ();
sv_2mortal ((SV *) RETVALO);
/ * hacer algo con RETVAL * /
SALIDA:
RETVALO

Recuerde que no tiene que hacer esto para un "SV *". La documentación de referencia para todos
Los mapas de tipos básicos se pueden encontrar en perlxstypemap.

El proyecto MÓDULO Palabra clave
La palabra clave MODULE se utiliza para iniciar el código XS y especificar el paquete del
funciones que se están definiendo. Todo el texto que precede a la primera palabra clave MODULE es
considerado código C y se pasa a la salida con POD eliminado, pero de lo contrario
intacto. Cada módulo XS tendrá una función de arranque que se utiliza para conectar los XSUB
en Perl. El nombre del paquete de esta función de arranque coincidirá con el valor de la última
Sentencia MODULE en los archivos fuente XS. El valor de MODULE siempre debe permanecer
constante dentro del mismo archivo XS, aunque esto no es necesario.

El siguiente ejemplo iniciará el código XS y colocará todas las funciones en un paquete
llamado RPC.

MÓDULO = RPC

El proyecto PAQUETE Palabra clave
Cuando las funciones dentro de un archivo fuente XS deben separarse en paquetes, el PAQUETE
se debe utilizar la palabra clave. Esta palabra clave se usa con la palabra clave MODULE y debe seguir
inmediatamente después cuando se usa.

MÓDULO = PAQUETE RPC = RPC

[Código XS en el paquete RPC]

MÓDULO = PAQUETE RPC = RPCB

[Código XS en el paquete RPCB]

MÓDULO = PAQUETE RPC = RPC

[Código XS en el paquete RPC]

El mismo nombre de paquete se puede utilizar más de una vez, lo que permite un código no contiguo. Esta
es útil si tiene un principio de ordenación más sólido que los nombres de paquetes.

Aunque esta palabra clave es opcional y en algunos casos proporciona información redundante,
siempre debe usarse. Esta palabra clave asegurará que los XSUB aparezcan en el lugar deseado.
Pack

El proyecto PREFIJO Palabra clave
La palabra clave PREFIX designa prefijos que deben eliminarse de la función Perl
nombres. Si la función C es "rpcb_gettime ()" y el valor PREFIX es "rpcb_", entonces Perl
verá esta función como "gettime ()".

Esta palabra clave debe seguir a la palabra clave PACKAGE cuando se utilice. Si el PAQUETE no se usa entonces
PREFIX debe seguir a la palabra clave MODULE.

MÓDULO = PREFIJO DE RPC = rpc_

MÓDULO = PAQUETE RPC = PREFIJO RPCB = rpcb_

El proyecto SALIDA: Palabra clave
La palabra clave OUTPUT: indica que ciertos parámetros de función deben actualizarse (nuevo
valores visibles para Perl) cuando el XSUB termina o que ciertos valores deben ser
volvió a la función de Perl que llama. Para funciones simples que no tienen CÓDIGO: o
PPCODE: sección, como la sin () función anterior, la variable RETVAL es automáticamente
designado como un valor de salida. Para funciones más complejas, xsubpp el compilador necesitará
ayudar a determinar qué variables son variables de salida.

Esta palabra clave se utilizará normalmente para complementar la palabra clave CODE :. La variable RETVAL
no se reconoce como una variable de salida cuando la palabra clave CODE: está presente. La salida:
La palabra clave se usa en esta situación para decirle al compilador que RETVAL realmente es una salida
variable.

La palabra clave OUTPUT: también se puede utilizar para indicar que los parámetros de función se emiten
variables. Esto puede ser necesario cuando se ha modificado un parámetro dentro de la función.
y al programador le gustaría que Perl vea la actualización.

bool_t
rpcb_gettime (host, timep)
char * anfitrión
time_t & timep
SALIDA:
tiempop

La palabra clave OUTPUT: también permitirá que un parámetro de salida se asigne a una pieza coincidente
de código en lugar de un mapa de tipos.

bool_t
rpcb_gettime (host, timep)
char * anfitrión
time_t & timep
SALIDA:
timep sv_setnv (ST(1), (doble) tiempop);

xsubpp emite un "SvSETMAGIC ()" automático para todos los parámetros en la sección SALIDA del
XSUB, excepto RETVAL. Este es el comportamiento generalmente deseado, ya que se ocupa adecuadamente
invocar la magia 'set' en los parámetros de salida (necesario para los parámetros de elementos de matriz o hash
que deben crearse si no existieran). Si por alguna razón, este comportamiento no es
deseado, la sección de SALIDA puede contener una línea "SETMAGIC: DISABLE" para deshabilitarlo para el
resto de los parámetros en la sección SALIDA. Del mismo modo, "SETMAGIC: ENABLE" se puede
utilizado para volver a habilitarlo durante el resto de la sección SALIDA. Ver perlguts para más
detalles sobre la magia 'set'.

El proyecto NINGUNA SALIDA Palabra clave
El NO_OUTPUT se puede colocar como el primer token del XSUB. Esta palabra clave indica que
mientras que la subrutina C a la que proporcionamos una interfaz tiene un tipo de retorno no "nulo", el retorno
El valor de esta subrutina C no debe devolverse desde la subrutina Perl generada.

Con esta palabra clave presente se crea "La Variable RETVAL", y en la llamada generada a
la subrutina a la que está asignada esta variable, pero el valor de esta variable no va
para ser utilizado en el código generado automáticamente.

Esta palabra clave solo tiene sentido si el usuario proporcionado por el usuario va a acceder a "RETVAL"
código. Es especialmente útil hacer una interfaz de función más parecida a Perl, especialmente
cuando el valor de retorno de C es solo un indicador de condición de error. Por ejemplo,

NO_SALIDA int
delete_file (char * nombre)
POSTAL:
si (RETVAL! = 0)
croak ("Error% d al eliminar el archivo '% s'", RETVAL, nombre);

Aquí, la función XS generada no devuelve nada en caso de éxito, y morir () y un toque
mensaje de error significativo en caso de error.

El proyecto CÓDIGO: Palabra clave
Esta palabra clave se utiliza en XSUB más complicados que requieren un manejo especial para C
función. La variable RETVAL todavía se declara, pero no se devolverá a menos que sea
especificado en la sección SALIDA :.

El siguiente XSUB es para una función C que requiere un manejo especial de sus parámetros.
Primero se da el uso de Perl.

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

Sigue el XSUB.

bool_t
rpcb_gettime (host, timep)
char * anfitrión
tiempo_t tiempop
CÓDIGO:
RETVAL = rpcb_gettime (host, & timep);
SALIDA:
tiempop
RETVALO

El proyecto EN ESO: Palabra clave
La palabra clave INIT: permite insertar la inicialización en XSUB antes que el compilador
genera la llamada a la función C. A diferencia de la palabra clave CÓDIGO: anterior, esta palabra clave no
no afecta la forma en que el compilador maneja RETVAL.

bool_t
rpcb_gettime (host, timep)
char * anfitrión
time_t & timep
EN ESO:
printf ("# El host es% s \ n", host);
SALIDA:
tiempop

Otro uso de la sección INIT: es verificar las condiciones previas antes de hacer una llamada a
la función C:

largo largo
lldiv (a, b)
mucho tiempo un
largo largo b
EN ESO:
si (a == 0 && b == 0)
XSRETURN_UNDEF;
si (b == 0)
croak ("lldiv: no se puede dividir entre 0");

El proyecto NO_INIT Palabra clave
La palabra clave NO_INIT se usa para indicar que un parámetro de función se usa solo como un
valor de salida. los xsubpp El compilador normalmente generará código para leer los valores de todos
Parámetros de función de la pila de argumentos y asignarlos a variables C al ingresar a
la función. NO_INIT le dirá al compilador que algunos parámetros se usarán para la salida
en lugar de para la entrada y que se manejarán antes de que finalice la función.

El siguiente ejemplo muestra una variación del rpcb_gettime () función. Esta función
usa la variable timep solo como una variable de salida y no se preocupa por su valor inicial
contenido.

bool_t
rpcb_gettime (host, timep)
char * anfitrión
time_t & timep = NO_INIT
SALIDA:
tiempop

El proyecto MAPA DE TIPOS: Palabra clave
A partir de Perl 5.16, puede incrustar typemaps en su código XS en lugar de o en
además de typemaps en un archivo separado. Múltiples mapas de tipos incrustados serán
procesados ​​en orden de aparición en el código XS y, al igual que los archivos de mapa de tipos locales, toman
precedencia sobre el typemap predeterminado, los typemaps incrustados pueden sobrescribir los
definiciones de las estrofas TYPEMAP, INPUT y OUTPUT. La sintaxis de los mapas de tipos incrustados es

TYPEMAP: <
... su código typemap aquí ...
AQUÍ

donde la palabra clave "TYPEMAP" debe aparecer en la primera columna de una nueva línea.

Consulte perlxstypemap para obtener detalles sobre cómo escribir mapas de tipos.

Inicializando Función parámetros
Los parámetros de la función C normalmente se inicializan con sus valores de la pila de argumentos
(que a su vez contiene los parámetros que se pasaron al XSUB desde Perl). los
Los mapas de tipos contienen los segmentos de código que se utilizan para traducir los valores de Perl a C
parámetros. Sin embargo, el programador puede anular los mapas de tipos y proporcionar
código de inicialización alternativo (o adicional). El código de inicialización comienza con el primero
"=", ";" o "+" en una línea en la sección INPUT :. La única excepción ocurre si este ";"
termina la línea, entonces este ";" se ignora en silencio.

El siguiente código demuestra cómo proporcionar código de inicialización para parámetros de función.
El compilador evalúa el código de inicialización entre comillas dobles antes de agregarlo
a la salida, por lo que cualquier cosa que deba interpretarse literalmente [principalmente "$", "@" o "\\"]
debe estar protegido con barras invertidas. Las variables $ var, $ arg y $ type se pueden usar como en
mapas tipográficos.

bool_t
rpcb_gettime (host, timep)
char * host = (char *) SvPV_nolen ($ arg);
time_t & timep = 0;
SALIDA:
tiempop

Esto no debe usarse para proporcionar valores predeterminados para parámetros. Uno normalmente usaría
esto cuando un parámetro de función debe ser procesado por otra función de biblioteca antes de que pueda
ser usado. Los parámetros predeterminados se tratan en la siguiente sección.

Si la inicialización comienza con "=", se emite en la declaración de la entrada.
variable, reemplazando la inicialización proporcionada por el typemap. Si la inicialización
empieza con ";" o "+", entonces se realiza después de que todas las variables de entrada hayan sido
declarado. En el ";" caso de que la inicialización normalmente proporcionada por el typemap no sea
realizado. Para el caso "+", la declaración de la variable incluirá el
inicialización desde el typemap. Una variable global,% v, está disponible para los verdaderamente raros
caso en el que se necesita información de una inicialización en otra inicialización.

Aquí hay un ejemplo realmente oscuro:

bool_t
rpcb_gettime (host, timep)
time_t & timep; / * \ $ v {tiempop} = @ {[$ v {tiempop} = $ arg]} * /
char * host + SvOK ($ v {timep})? SvPV_nolen ($ arg): NULL;
SALIDA:
tiempop

La construcción "\ $ v {timep} = @ {[$ v {timep} = $ arg]}" utilizada en el ejemplo anterior tiene dos
propósito: primero, cuando esta línea es procesada por xsubpp, el fragmento de Perl "$ v {timep} = $ arg"
se evalúa. En segundo lugar, el texto del fragmento evaluado se envía al archivo C generado
archivo (dentro de un comentario de C)! Durante el procesamiento de la línea "char * host", $ arg evaluará
a ST(0) y $ v {timep} evaluará ST(1).

Predeterminado Parámetro Valores
Los valores predeterminados para los argumentos XSUB se pueden especificar colocando una instrucción de asignación en
la lista de parámetros. El valor predeterminado puede ser un número, una cadena o la cadena especial
"NO_INIT". Los valores predeterminados siempre deben usarse solo en los parámetros más a la derecha.

Para permitir que el XSUB rpcb_gettime () para tener un valor de host predeterminado los parámetros para el
XSUB podría reorganizarse. El XSUB luego llamará al real rpcb_gettime () funcionar con
los parámetros en el orden correcto. Este XSUB se puede llamar desde Perl con cualquiera de los
siguiendo instrucciones:

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

$ estado = rpcb_gettime ($ timep);

El XSUB se verá como el código que sigue. Un bloque CÓDIGO: se utiliza para llamar al
real rpcb_gettime () función con los parámetros en el orden correcto para esa función.

bool_t
rpcb_gettime (timep, host = "localhost")
char * anfitrión
tiempo_t tiempop = NO_INIT
CÓDIGO:
RETVAL = rpcb_gettime (host, & timep);
SALIDA:
tiempop
RETVALO

El proyecto PREINICIO: Palabra clave
La palabra clave PREINIT: permite declarar variables adicionales inmediatamente antes o después de la
se emiten declaraciones de los parámetros de la sección INPUT :.

Si se declara una variable dentro de una sección CODE: seguirá cualquier código typemap que sea
emitido para los parámetros de entrada. Esto puede resultar en que la declaración termine después de C
código, que es un error de sintaxis C. Pueden ocurrir errores similares con un explícito ";" - tipo o
Se utiliza la inicialización de parámetros de tipo "+" (consulte "Inicialización de parámetros de función").
Declarar estas variables en una sección INIT: no ayudará.

En tales casos, para forzar la declaración de una variable adicional junto con las declaraciones
de otras variables, coloque la declaración en una sección PREINIT :. La palabra clave PREINIT:
se puede utilizar una o más veces dentro de un XSUB.

Los siguientes ejemplos son equivalentes, pero si el código utiliza mapas de tipos complejos,
El primer ejemplo es más seguro.

bool_t
rpcb_gettime (timep)
tiempo_t tiempop = NO_INIT
PREINICIO:
char * host = "localhost";
CÓDIGO:
RETVAL = rpcb_gettime (host, & timep);
SALIDA:
tiempop
RETVALO

Para este caso particular, una palabra clave INIT: generaría el mismo código C que PREINIT:
palabra clave. Otro ejemplo correcto, pero propenso a errores:

bool_t
rpcb_gettime (timep)
tiempo_t tiempop = NO_INIT
CÓDIGO:
char * host = "localhost";
RETVAL = rpcb_gettime (host, & timep);
SALIDA:
tiempop
RETVALO

Otra forma de declarar "host" es usar un bloque C en la sección CÓDIGO::

bool_t
rpcb_gettime (timep)
tiempo_t tiempop = NO_INIT
CÓDIGO:
{
char * host = "localhost";
RETVAL = rpcb_gettime (host, & timep);
}
SALIDA:
tiempop
RETVALO

La capacidad de poner declaraciones adicionales antes de que se procesen las entradas del mapa de tipos es
muy útil en los casos en que las conversiones de mapas de tipos manipulan algún estado global:

Myobject
mutar (o)
PREINICIO:
MiEstado st = estado_global;
ENTRADA:
MiObjeto o;
LIMPIAR:
reset_to (estado_global, st);

Aquí suponemos que la conversión a "MyObject" en la sección INPUT: y desde MyObject cuando
el procesamiento de RETVAL modificará una variable global "global_state". Después de estas conversiones
se realizan, restauramos el antiguo valor de "global_state" (para evitar pérdidas de memoria, por
ejemplo).

Hay otra forma de intercambiar claridad por compacidad: las secciones INPUT permiten la declaración de
Variables C que no aparecen en la lista de parámetros de una subrutina. Así lo anterior
código para mudar() puede reescribirse como

Myobject
mutar (o)
MiEstado st = estado_global;
MiObjeto o;
LIMPIAR:
reset_to (estado_global, st);

y el código para rpcb_gettime () puede reescribirse como

bool_t
rpcb_gettime (timep)
tiempo_t tiempop = NO_INIT
char * host = "localhost";
C_ARGS:
host y timep
SALIDA:
tiempop
RETVALO

El proyecto ALCANCE: Palabra clave
La palabra clave SCOPE: permite habilitar el alcance para un XSUB en particular. Si está habilitado, el
XSUB invocará ENTER y LEAVE automáticamente.

Para admitir asignaciones de tipos potencialmente complejas, si una entrada de asignación de tipos utilizada por un XSUB contiene
un comentario como "/ * alcance * /", el alcance se habilitará automáticamente para ese XSUB.

Para habilitar el alcance:

ALCANCE: HABILITAR

Para deshabilitar el alcance:

ALCANCE: DESACTIVAR

El proyecto ENTRADA: Palabra clave
Los parámetros del XSUB generalmente se evalúan inmediatamente después de ingresar al XSUB. los
INPUT: la palabra clave se puede usar para forzar que esos parámetros se evalúen un poco más tarde. los
ENTRADA: la palabra clave se puede usar varias veces dentro de un XSUB y se puede usar para enumerar una o
más variables de entrada. Esta palabra clave se utiliza con PREINIT: palabra clave.

El siguiente ejemplo muestra cómo el parámetro de entrada "timep" se puede evaluar tarde, después de un
PREINICIO

bool_t
rpcb_gettime (host, timep)
char * anfitrión
PREINICIO:
tiempo_t tt;
ENTRADA:
tiempo_t tiempop
CÓDIGO:
RETVAL = rpcb_gettime (host, & tt);
tiempop = tt;
SALIDA:
tiempop
RETVALO

El siguiente ejemplo muestra cada parámetro de entrada evaluado tarde.

bool_t
rpcb_gettime (host, timep)
PREINICIO:
tiempo_t tt;
ENTRADA:
char * anfitrión
PREINICIO:
char * h;
ENTRADA:
tiempo_t tiempop
CÓDIGO:
h = anfitrión;
RETVAL = rpcb_gettime (h, & tt);
tiempop = tt;
SALIDA:
tiempop
RETVALO

Dado que las secciones INPUT permiten la declaración de variables C que no aparecen en el parámetro
lista de una subrutina, esto puede reducirse a:

bool_t
rpcb_gettime (host, timep)
tiempo_t tt;
char * host;
char * h = anfitrión;
tiempo_t tiempop;
CÓDIGO:
RETVAL = rpcb_gettime (h, & tt);
tiempop = tt;
SALIDA:
tiempop
RETVALO

(Usamos nuestro conocimiento de que la conversión de entrada para "char *" es "simple", por lo tanto, "host"
se inicializa en la línea de declaración, y nuestra asignación "h = host" no se realiza también
temprano. De lo contrario, se necesitaría tener la asignación "h = host" en un CÓDIGO: o INIT:
sección.)

El proyecto IN / OUTLIST / IN_OUTLIST / OUT / IN_OUT PALABRAS CLAVE
En la lista de parámetros para un XSUB, se pueden preceder los nombres de los parámetros por el
Palabras clave "IN" / "OUTLIST" / "IN_OUTLIST" / "OUT" / "IN_OUT". La palabra clave "IN" es la predeterminada, la
otras palabras clave indican cómo la interfaz de Perl debe diferir de la interfaz de C.

Los parámetros precedidos por palabras clave "OUTLIST" / "IN_OUTLIST" / "OUT" / "IN_OUT" se consideran
utilizado por la subrutina C vía punteros. Las palabras clave "OUTLIST" / "OUT" indican que la C
La subrutina no inspecciona la memoria apuntada por este parámetro, pero escribirá
este puntero para proporcionar valores de retorno adicionales.

Los parámetros precedidos por la palabra clave "OUTLIST" no aparecen en la firma de uso del
función de Perl generada.

Parámetros precedidos por "IN_OUTLIST" / "IN_OUT" / "OUT" do aparecen como parámetros para el Perl
función. Con la excepción de los parámetros "OUT", estos parámetros se convierten al
correspondiente al tipo C, entonces los punteros a estos datos se dan como argumentos a la C
función. Se espera que la función C escriba a través de estos punteros.

La lista de retorno de la función de Perl generada consta del valor de retorno C de la
función (a menos que el XSUB sea del tipo de retorno "nulo" o se haya utilizado "La palabra clave NO_OUTPUT")
seguido de todos los parámetros "OUTLIST" e "IN_OUTLIST" (en el orden de aparición).
A la vuelta del XSUB, el parámetro de Perl "IN_OUT" / "OUT" se modificará para tener el
valores escritos por la función C.

Por ejemplo, un XSUB

vacío
day_month (OUTLIST día, IN unix_time, OUTLIST mes)
día internacional
int tiempo_unix
mes int

debe usarse desde Perl como

my ($ día, $ mes) = day_month (hora);

La firma C de la función correspondiente debe ser

void day_month (int * día, int unix_time, int * mes);

Las palabras clave "IN" / "OUTLIST" / "IN_OUTLIST" / "IN_OUT" / "OUT" se pueden mezclar con el estilo ANSI
declaraciones, como en

vacío
day_month (OUTLIST int día, int unix_time, OUTLIST int mes)

(aquí se omite la palabra clave opcional "IN").

Los parámetros "IN_OUT" son idénticos a los parámetros introducidos con "The & Unary
Operador "y ponerlo en la sección" SALIDA: "(consulte" La SALIDA: palabra clave ").
Los parámetros "IN_OUTLIST" son muy similares, la única diferencia es que el valor C
La función escribe a través del puntero no modificaría el parámetro Perl, pero se coloca en el
lista de salida.

El parámetro "OUTLIST" / "OUT" difieren de los parámetros "IN_OUTLIST" / "IN_OUT" solo por el
el valor inicial del parámetro Perl no se lee (y no se le da a la función C
- que obtiene algo de basura en su lugar). Por ejemplo, la misma función C que la anterior puede ser
interconectado con como

void day_month (OUT int día, int unix_time, OUT int mes);

or

vacío
day_month (día, unix_time, mes)
int & day = NO_INIT
int tiempo_unix
int & month = NO_INIT
SALIDA:
day
mes

Sin embargo, la función de Perl generada se llama en un estilo muy C-ish:

my ($ día, $ mes);
day_month ($ día, hora, $ mes);

El proyecto "longitud (NOMBRE)" Palabra clave
Si uno de los argumentos de entrada a la función C es la longitud de un argumento de cadena "NOMBRE",
se puede sustituir el nombre del argumento de longitud por "longitud (NOMBRE)" en el XSUB
declaración. Este argumento debe omitirse cuando se llama a la función Perl generada.
P.ej

vacío
dump_chars (char * s, l corto)
{
corto n = 0;
while (n <l) {
printf ("s [% d] = \" \\% # 03o \ "\ n", n, (int) s [n]);
n ++;
}
}

MÓDULO = x PAQUETE = x

void dump_chars (char * s, short length (s))

debería llamarse como "dump_chars ($ string)".

Esta directiva solo es compatible con declaraciones de funciones de tipo ANSI.

Longitud variable Parámetro Listas
Los XSUB pueden tener listas de parámetros de longitud variable especificando puntos suspensivos "(...)" en el
lista de parámetros. Este uso de los puntos suspensivos es similar al que se encuentra en ANSI C.
El programador puede determinar el número de argumentos pasados ​​al XSUB examinando
la variable "elementos" que el xsubpp suministros del compilador para todos los XSUB. Al usar esto
mecanismo uno puede crear un XSUB que acepta una lista de parámetros de longitud desconocida.

El proyecto fortaleza parámetro para la rpcb_gettime () XSUB puede ser opcional, por lo que se pueden utilizar puntos suspensivos
para indicar que el XSUB tomará un número variable de parámetros. Perl debería poder
para llamar a este XSUB con cualquiera de las siguientes declaraciones.

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

$ estado = rpcb_gettime ($ timep);

A continuación, se muestra el código XS, con puntos suspensivos.

bool_t
rpcb_gettime (timep, ...)
tiempo_t tiempop = NO_INIT
PREINICIO:
char * host = "localhost";
CÓDIGO:
si (elementos> 1)
host = (char *) SvPV_nolen (ST(1));
RETVAL = rpcb_gettime (host, & timep);
SALIDA:
tiempop
RETVALO

El proyecto C_ARGS: Palabra clave
La palabra clave C_ARGS: permite la creación de XSUBS que tienen una secuencia de llamada diferente de
Perl que desde C, sin necesidad de escribir la sección CODE: o PPCODE :. El contenido del
C_ARGS: el párrafo se pone como argumento de la función C llamada sin ningún cambio.

Por ejemplo, suponga que una función C se declara como

simbólico nth_derivative (int n, función simbólica, int flags);

y que las banderas predeterminadas se mantienen en una variable C global "default_flags". Suponer que
desea crear una interfaz que se llama como

$ second_deriv = $ función->derivada_enésima(2);

Para hacer esto, declare el XSUB como

simbólico
nth_derivative (función, n)
función simbólica
int sustantivo, masculino—
C_ARGS:
n, función, default_flags

El proyecto CÓDIGOPP: Palabra clave
La palabra clave PPCODE: es una forma alternativa de la palabra clave CODE: y se utiliza para indicar la
xsubpp compilador que el programador está proporcionando el código para controlar la pila de argumentos
para los valores de retorno de XSUB. Ocasionalmente, uno querrá que un XSUB devuelva una lista de
valores en lugar de un valor único. En estos casos se debe usar PPCODE: y luego
Empuje explícitamente la lista de valores en la pila. Las palabras clave PPCODE: y CODE: deben
no deben usarse juntos dentro del mismo XSUB.

La diferencia real entre las secciones PPCODE: y CODE: está en la inicialización de "SP"
macro (que significa corriente Puntero de pila de Perl), y en el manejo de datos en
la pila al regresar de un XSUB. En CÓDIGO: las secciones SP conserva el valor que se
al ingresar al XSUB: SP está en el puntero de función (que sigue al último parámetro).
En PPCODE: las secciones SP se mueven hacia atrás al principio de la lista de parámetros, que
permite que las macros "PUSH * ()" coloquen los valores de salida en el lugar que Perl espera que estén cuando
el XSUB vuelve a Perl.

El tráiler generado para una sección CÓDIGO: asegura que el número de valores de retorno de Perl
verá es 0 o 1 (dependiendo del "vacío" del valor de retorno de la C
función y heurísticas mencionadas en "La variable RETVAL"). El tráiler generado para un
PPCODE: la sección se basa en el número de valores devueltos y en el número de veces "SP"
fue actualizado por macros "[X] PUSH * ()".

Tenga en cuenta que las macros ST (i), "XST_m * ()" y "XSRETURN * ()" funcionan igualmente bien en las secciones CODE:
y PPCODE: secciones.

El siguiente XSUB llamará al C rpcb_gettime () función y devolverá sus dos salidas
valores, timep y status, a Perl como una sola lista.

vacío
rpcb_gettime (anfitrión)
char * anfitrión
PREINICIO:
tiempo_t tiempop;
estado bool_t;
CÓDIGOPP:
status = rpcb_gettime (host, & timep);
EXTENDER (SP, 2);
PUSHs (sv_2mortal (newSViv (estado)));
PUSHs (sv_2mortal (newSViv (timep)));

Tenga en cuenta que el programador debe proporcionar el código C necesario para tener el
rpcb_gettime () función llamada y tener los valores de retorno correctamente colocados en el
pila de argumentos.

El tipo de retorno "void" para esta función le dice al xsubpp compilador que el RETVAL
La variable no es necesaria ni utilizada y no debe crearse. En la mayoría de los escenarios,
El tipo de retorno void debe usarse con la directiva PPCODE :.

El proyecto AMPLIAR() La macro se usa para hacer espacio en la pila de argumentos para 2 valores de retorno. los
PPCODE: la directiva hace que xsubpp compilador para crear un puntero de pila disponible como "SP",
y es este puntero el que se utiliza en el AMPLIAR() macro. Los valores son entonces
empujado a la pila con el PUSHs () macro.

Ahora la rpcb_gettime () La función se puede utilizar desde Perl con la siguiente declaración.

($ estado, $ tiempop) = rpcb_gettime ("localhost");

Cuando maneje los parámetros de salida con una sección PPCODE, asegúrese de manejar la magia 'set'
adecuadamente. Consulte perlguts para obtener detalles sobre la magia 'set'.

Volviendo indefenso Y Vacío Listas
Ocasionalmente, el programador querrá devolver simplemente "undef" o una lista vacía si un
la función falla en lugar de un valor de estado separado. los rpcb_gettime () ofertas de funciones
solo esta situación. Si la función tiene éxito, nos gustaría que devuelva la hora.
y si falla, nos gustaría que se devolviera undef. En el siguiente código Perl el
el valor de $ timep será indefinido o será un tiempo válido.

$ timep = rpcb_gettime ("localhost");

El siguiente XSUB usa el tipo de retorno "SV *" solo como mnemónico y usa un bloque CODE:
para indicar al compilador que el programador ha proporcionado todo el código necesario. los
sv_newmortal () La llamada inicializará el valor de retorno a undef, lo que lo convierte en el valor predeterminado
valor de retorno.

VS *
rpcb_gettime (anfitrión)
char * anfitrión
PREINICIO:
tiempo_t tiempop;
bool_tx;
CÓDIGO:
ST(0) = sv_newmortal ();
if (rpcb_gettime (host y timep))
sv_setnv ( ST(0), (doble) tiempop);

El siguiente ejemplo demuestra cómo se colocaría un indef explícito en el valor de retorno,
si surgiera la necesidad.

VS *
rpcb_gettime (anfitrión)
char * anfitrión
PREINICIO:
tiempo_t tiempop;
bool_tx;
CÓDIGO:
if (rpcb_gettime (host y timep)) {
ST(0) = sv_newmortal ();
sv_setnv ( ST(0), (doble) tiempop);
}
más{
ST(0) = & PL_sv_undef;
}

Para devolver una lista vacía, uno debe usar un bloque PPCODE: y luego no presionar valores de retorno en
la pila.

vacío
rpcb_gettime (anfitrión)
char * anfitrión
PREINICIO:
tiempo_t tiempop;
CÓDIGOPP:
if (rpcb_gettime (host y timep))
PUSHs (sv_2mortal (newSViv (timep)));
más{
/ * Nada empujado en la pila, por lo que un vacío
* La lista se devuelve implícitamente. * /
}

Algunas personas pueden inclinarse a incluir una "devolución" explícita en el XSUB anterior, en lugar de
dejando que el control caiga hasta el final. En esas situaciones, "XSRETURN_EMPTY" debe ser
utilizado, en su lugar. Esto asegurará que la pila XSUB esté correctamente ajustada. Consultar
perlapi para otras macros "XSRETURN".

Dado que las macros "XSRETURN_ *" también se pueden usar con bloques CODE, se puede reescribir esto
ejemplo como:

int
rpcb_gettime (anfitrión)
char * anfitrión
PREINICIO:
tiempo_t tiempop;
CÓDIGO:
RETVAL = rpcb_gettime (host, & timep);
si (RETVAL == 0)
XSRETURN_UNDEF;
SALIDA:
RETVALO

De hecho, también se puede poner este cheque en una sección POSTCALL :. Junto con PREINIT:
simplificaciones, esto conduce a:

int
rpcb_gettime (anfitrión)
char * anfitrión
tiempo_t tiempop;
POSTAL:
si (RETVAL == 0)
XSRETURN_UNDEF;

El proyecto EXIGIR: Palabra clave
La palabra clave REQUIRE: se utiliza para indicar la versión mínima del xsubpp compilador necesario
para compilar el módulo XS. Un módulo XS que contiene la siguiente declaración
compilar solo con xsubpp versión 1.922 o superior:

REQUERIR: 1.922

El proyecto LIMPIAR: Palabra clave
Esta palabra clave se puede utilizar cuando un XSUB requiere procedimientos de limpieza especiales antes de
termina. Cuando se utiliza la palabra clave CLEANUP: debe seguir cualquier CÓDIGO: o SALIDA:
bloques que están presentes en el XSUB. El código especificado para el bloque de limpieza será
agregado como las últimas declaraciones en el XSUB.

El proyecto POSTAL: Palabra clave
Esta palabra clave se puede utilizar cuando un XSUB requiere la ejecución de procedimientos especiales después de la C
se realiza la llamada de subrutina. Cuando se utiliza la palabra clave POSTCALL: debe preceder a OUTPUT:
y CLEANUP: bloques que están presentes en el XSUB.

Vea ejemplos en "La palabra clave NO_OUTPUT" y "Devolución de listas vacías y undef".

El bloque POSTCALL: no tiene mucho sentido cuando la llamada de subrutina C es suministrada por
usuario proporcionando la sección CODE: o PPCODE :.

El proyecto BOTA: Palabra clave
La palabra clave BOOT: se usa para agregar código a la función de arranque de la extensión. los
La función bootstrap es generada por la xsubpp compilador y normalmente contiene las declaraciones
necesario para registrar cualquier XSUB con Perl. Con la palabra clave BOOT: el programador puede decir
el compilador para agregar declaraciones adicionales a la función de arranque.

Esta palabra clave puede usarse en cualquier momento después de la primera palabra clave MODULE y debe aparecer en un
línea por sí misma. La primera línea en blanco después de la palabra clave terminará el bloque de código.

BOTA:
# El siguiente mensaje se imprimirá cuando el
# Se ejecuta la función bootstrap.
printf ("¡Hola desde el programa de arranque! \ n");

El proyecto VERIFICACIÓN DE VERSIÓN: Palabra clave
La palabra clave VERSIONCHECK: corresponde a xsubpp"-versioncheck" y "-noversioncheck"
opciones. Esta palabra clave anula las opciones de la línea de comandos. La verificación de versión está habilitada por
defecto. Cuando la verificación de versión está habilitada, el módulo XS intentará verificar que su
La versión coincide con la versión del módulo PM.

Para habilitar la verificación de versiones:

VERSIONCHECK: HABILITAR

Para deshabilitar la verificación de versiones:

VERSIONCHECK: DESACTIVAR

Tenga en cuenta que si la versión del módulo PM es un NV (un número de punto flotante), será
encadenado con una posible pérdida de precisión (actualmente se reduce a nueve lugares decimales)
para que ya no coincida con la versión del módulo XS. Citando $ VERSION
Se recomienda una declaración para convertirlo en una cadena si se utilizan números de versión largos.

El proyecto PROTOTIPOS: Palabra clave
La palabra clave PROTOTIPOS: corresponde a xsubpplas opciones "-prototypes" y "-noprototypes".
Esta palabra clave anula las opciones de la línea de comandos. Los prototipos están habilitados de forma predeterminada. Cuando
los prototipos están habilitados Los XSUB recibirán prototipos de Perl. Esta palabra clave se puede utilizar
varias veces en un módulo XS para habilitar y deshabilitar prototipos para diferentes partes del
módulo.

Para habilitar prototipos:

PROTOTIPOS: HABILITAR

Para deshabilitar prototipos:

PROTOTIPOS: DESACTIVAR

El proyecto PROTOTIPO: Palabra clave
Esta palabra clave es similar a la palabra clave PROTOTIPOS: anterior, pero se puede usar para forzar xsubpp
para utilizar un prototipo específico para el XSUB. Esta palabra clave anula todos los demás prototipos.
opciones y palabras clave, pero solo afecta al XSUB actual. Consultar "Prototipos" en perlsub
para obtener información sobre los prototipos de Perl.

bool_t
rpcb_gettime (timep, ...)
tiempo_t tiempop = NO_INIT
PROTOTIPO: $; $
PREINICIO:
char * host = "localhost";
CÓDIGO:
si (elementos> 1)
host = (char *) SvPV_nolen (ST(1));
RETVAL = rpcb_gettime (host, & timep);
SALIDA:
tiempop
RETVALO

Si los prototipos están habilitados, puede deshabilitarlos localmente para un XSUB dado como en el
siguiente ejemplo:

vacío
rpcb_gettime_noproto ()
PROTOTIPO: DESACTIVAR
...

El proyecto AKA: Palabra clave
La palabra clave ALIAS: permite que un XSUB tenga dos o más nombres Perl únicos y sepa cuál
de esos nombres se utilizó cuando se invocó. Los nombres de Perl pueden estar completamente calificados con
nombres de paquetes. A cada alias se le asigna un índice. El compilador configurará una variable llamada
"ix" que contiene el índice del alias que se utilizó. Cuando se llama al XSUB con
su nombre declarado "ix" será 0.

El siguiente ejemplo creará los alias "FOO :: gettime ()" y "BAR :: getit ()" para esto
función.

bool_t
rpcb_gettime (host, timep)
char * anfitrión
time_t & timep
AKA:
FOO :: gettime = 1
BAR :: getit = 2
EN ESO:
printf ("# ix =% d \ n", ix);
SALIDA:
tiempop

El proyecto SOBRECARGA: Palabra clave
En lugar de escribir una interfaz sobrecargada usando Perl puro, también puede usar OVERLOAD
palabra clave para definir nombres de Perl adicionales para sus funciones (como la palabra clave ALIAS:
encima). Sin embargo, las funciones sobrecargadas deben definirse con tres parámetros (excepto
para sin metodo() función que necesita cuatro parámetros). Si alguna función tiene la
OVERLOAD: palabra clave, se definirán varias líneas adicionales en el archivo c generado por
xsubpp para registrarse con la magia de sobrecarga.

Dado que los objetos bendecidos se almacenan en realidad como vehículos recreativos, es útil utilizar el mapa de tipos
características para preprocesar los parámetros y extraer el SV real almacenado dentro del bendito RV.
Vea el ejemplo de T_PTROBJ_SPECIAL a continuación.

Para usar la palabra clave OVERLOAD:, cree una función XS que tome tres parámetros de entrada (
o use la definición de estilo c '...') así:

VS *
cmp (lobj, robj, intercambio)
Mi_módulo_obj lobj
Mi_módulo_obj robj
Intercambio intravenoso
SOBRECARGA: cmp <=>
{/ * función definida aquí * /}

En este caso, la función sobrecargará los dos operadores de comparación de tres vías. Para
todas las operaciones de sobrecarga que utilizan caracteres no alfabéticos, debe escribir el parámetro sin
citando, separando múltiples sobrecargas con espacios en blanco. Tenga en cuenta que "" (el stringify
sobrecarga) debe ingresarse como \ "\" (es decir, escapado).

El proyecto RETROCEDER: Palabra clave
Además de la palabra clave OVERLOAD, si necesita controlar cómo Perl autogenera
operadores sobrecargados, puede establecer la palabra clave FALLBACK en la sección de encabezado del módulo, como
modo:

MÓDULO = PAQUETE RPC = RPC

FALLBACK: VERDADERO
...

donde FALLBACK puede tomar cualquiera de los tres valores TRUE, FALSE o UNDEF. Si no configura
cualquier valor FALLBACK cuando se usa OVERLOAD, por defecto es UNDEF. FALLBACK no se utiliza excepto
cuando se han definido una o más funciones que utilizan OVERLOAD. Consulte "respaldo" en
sobrecarga para obtener más detalles.

El proyecto INTERFAZ: Palabra clave
Esta palabra clave declara el XSUB actual como guardián de la firma de llamada dada. Si
algún texto sigue a esta palabra clave, se considera como una lista de funciones que tienen esta
firma y debe adjuntarse al XSUB actual.

Por ejemplo, si tiene 4 funciones C multiplicar(), dividir(), añadir(), sustraer() todos teniendo
la firma:

simbólico f (simbólico, simbólico);

puede hacer que todos usen el mismo XSUB usando esto:

simbólico
interfaz_s_ss (arg1, arg2)
arg1 simbólico
arg2 simbólico
INTERFAZ:
multiplicar dividir
sumar restar

(¡Este es el código XSUB completo para 4 funciones de Perl!) Cuatro funciones de Perl generadas comparten
nombres con funciones C correspondientes.

La ventaja de este enfoque en comparación con ALIAS: palabra clave es que no es necesario
codificar una declaración de cambio, cada función de Perl (que comparte el mismo XSUB) sabe qué C
función que debería llamar. Además, se puede adjuntar una función adicional recordatorio() at
tiempo de ejecución usando

CV * mycv = newXSproto ("Simbólico :: resto",
XS_Symbolic_interface_s_ss, __FILE__, "$$");
XSINTERFACE_FUNC_SET (mycv, resto);

digamos, de otro XSUB. (Este ejemplo supone que no existía INTERFACE_MACRO:
sección, de lo contrario, es necesario utilizar otra cosa en lugar de "XSINTERFACE_FUNC_SET", consulte
la siguiente sección.)

El proyecto INTERFAZ_MACRO: Palabra clave
Esta palabra clave permite definir una INTERFAZ usando una forma diferente de extraer una función
puntero de un XSUB. El texto que sigue a esta palabra clave debe dar el nombre de las macros.
que extraería / establecería un puntero de función. A la macro extractora se le da un tipo de retorno,
"CV *" y "XSANY.any_dptr" para este "CV *". La macro de establecimiento se da cv, y el
puntero de función.

El valor predeterminado es "XSINTERFACE_FUNC" y "XSINTERFACE_FUNC_SET". Una palabra clave INTERFACE
con una lista vacía de funciones se puede omitir si se utiliza la palabra clave INTERFACE_MACRO.

Suponga que en el ejemplo anterior funciones punteros para multiplicar(), dividir(), añadir(),
sustraer() se mantienen en una matriz C global "fp []" con compensaciones siendo "multiply_off",
"dividir_apagar", "agregar_activar", "restar_apagar". Entonces uno puede usar

#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 la sección C,

simbólico
interfaz_s_ss (arg1, arg2)
arg1 simbólico
arg2 simbólico
INTERFAZ_MACRO:
XSINTERFACE_FUNC_BYOFFSET
XSINTERFACE_FUNC_BYOFFSET_conjunto
INTERFAZ:
multiplicar dividir
sumar restar

en la sección XSUB.

El proyecto INCLUIR: Palabra clave
Esta palabra clave se puede utilizar para introducir otros archivos en el módulo XS. Los otros archivos pueden tener
Código XS. INCLUYE: también se puede usar para ejecutar un comando para generar el código XS que se extraerá
en el módulo.

El archivo Rpcb1.xsh contiene nuestra función "rpcb_gettime ()":

bool_t
rpcb_gettime (host, timep)
char * anfitrión
time_t & timep
SALIDA:
tiempop

El módulo XS puede usar INCLUDE: para incorporar ese archivo.

INCLUYE: Rpcb1.xsh

Si los parámetros de la palabra clave INCLUDE: van seguidos de una barra vertical ("|"), el compilador
interpretará los parámetros como un comando. Esta función está ligeramente obsoleta en favor de
la directiva "INCLUDE_COMMAND:", como se documenta a continuación.

INCLUYE: cat Rpcb1.xsh |

No use esto para ejecutar perl: "INCLUDE: perl |" ejecutará el perl que resulta ser el
primero en su ruta y no necesariamente el mismo perl que se usa para ejecutar "xsubpp". Ver
"La palabra clave INCLUDE_COMMAND:".

El proyecto INCLUYE_COMANDO: Palabra clave
Ejecuta el comando proporcionado e incluye su salida en el documento XS actual.
"INCLUDE_COMMAND" asigna un significado especial al token $ ^ X ya que ejecuta el mismo perl
intérprete que está ejecutando "xsubpp":

INCLUYE_COMANDO: gato Rpcb1.xsh

INCLUYE_COMMAND: $ ^ X -e ...

El proyecto CASO: Palabra clave
La palabra clave CASE: permite que un XSUB tenga múltiples partes distintas con cada parte actuando como
un XSUB virtual. CASE: es codicioso y si se usa, todas las demás palabras clave XS deben ser
contenido dentro de un CASO :. Esto significa que nada puede preceder al primer CASO: en el XSUB y
todo lo que sigue al último CASE: se incluye en ese caso.

UN CASO: puede cambiar a través de un parámetro del XSUB, a través de la variable "ix" ALIAS: (ver "El
ALÍAS: Palabra clave "), o tal vez a través de la variable" elementos "(consulte" Parámetro de longitud variable
Listas "). El último CASO: se convierte en el tu préstamo estudiantil caso si no está asociado con un
condicional. El siguiente ejemplo muestra CASE conmutado a través de "ix" con una función
"rpcb_gettime ()" que tiene un alias "x_gettime ()". Cuando la función se llama como
"rpcb_gettime ()" sus parámetros son los habituales "(char * host, time_t * timep)", pero cuando el
la función se llama como "x_gettime ()" sus parámetros se invierten, "(time_t * timep, char
*anfitrión)".

long
rpcb_gettime (a, b)
CASO: ix == 1
AKA:
x_gettime = 1
ENTRADA:
# 'a' es timep, 'b' es host
char * b
tiempo_t a = NO_INIT
CÓDIGO:
RETVAL = rpcb_gettime (b, & a);
SALIDA:
a
RETVALO
CASO:
# 'a' es host, 'b' es timep
char * a
time_t & b = NO_INIT
SALIDA:
b
RETVALO

Esa función se puede llamar con cualquiera de las siguientes declaraciones. Note las diferentes
listas de argumentos.

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

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

El proyecto EXPORTAR_XSUB_SÍMBOLOS: Palabra clave
La palabra clave EXPORT_XSUB_SYMBOLS: probablemente sea algo que nunca necesitará. En perl
versiones anteriores a 5.16.0, esta palabra clave no hace nada. A partir de 5.16, símbolos XSUB
ya no se exportan de forma predeterminada. Es decir, son funciones "estáticas". Si incluye

EXPORTAR_XSUB_SÍMBOLOS: HABILITAR

en su código XS, los XSUB que siguen a esta línea no se declararán "estáticos". Usted puede
luego deshabilite esto con

EXPORTAR_XSUB_SÍMBOLOS: DESHABILITAR

que, de nuevo, es el valor predeterminado que probablemente nunca debería cambiar. No puedes usar esto
palabra clave en versiones de perl anteriores a la 5.16 para hacer que los XSUB sean "estáticos".

El proyecto & Unario Operador
El operador unario "&" en la sección INPUT: se usa para indicar xsubpp que debería convertir
un valor Perl a / desde C usando el tipo C a la izquierda de "&", pero proporcione un puntero a esto
valor cuando se llama a la función C.

Esto es útil para evitar un bloque CODE: para una función C que toma un parámetro por
referencia. Normalmente, el parámetro no debe ser un tipo de puntero (un "int" o "long" pero
no es un "int *" o "long *").

El siguiente XSUB generará un código C incorrecto. los xsubpp el compilador convertirá esto
en el código que llama a "rpcb_gettime ()" con los parámetros "(char * host, time_t timep)", pero
el "rpcb_gettime ()" real quiere que el parámetro "timep" sea del tipo "time_t *" en lugar de
"tiempo_t".

bool_t
rpcb_gettime (host, timep)
char * anfitrión
tiempo_t tiempop
SALIDA:
tiempop

Ese problema se corrige utilizando el operador "&". los xsubpp el compilador ahora se convertirá
esto en el código que llama a "rpcb_gettime ()" correctamente con los parámetros "(char * host, time_t
* timep) ". Para ello, lleva el" & ", por lo que la llamada a la función se parece a
"rpcb_gettime (host y timep)".

bool_t
rpcb_gettime (host, timep)
char * anfitrión
time_t & timep
SALIDA:
tiempop

Inserción VAINA, Comentarios C Preprocesador instrucciones
Las directivas del preprocesador C están permitidas dentro de BOOT :, PREINIT: INIT :, CODE :, PPCODE :,
POSTCALL :, y CLEANUP: bloques, así como fuera de las funciones. Se permiten comentarios
en cualquier lugar después de la palabra clave MODULE. El compilador pasará las directivas del preprocesador
sin tocar y eliminará las líneas comentadas. La documentación POD está permitida en cualquier
punto, tanto en las secciones de lenguaje C como XS. El POD debe terminar con "= cut"
mando; "xsubpp" se cerrará con un error si no es así. Es muy poco probable que los humanos
El código C generado se confundirá con POD, ya que la mayoría de los estilos de sangría dan como resultado espacios en blanco
delante de cualquier línea que comience con "=". Los archivos XS generados por máquina pueden caer en esta trampa
a menos que se tenga cuidado de asegurar que un espacio rompa la secuencia "\ n =".

Se pueden agregar comentarios a XSUB colocando un "#" como el primer espacio no en blanco de una línea.
Se debe tener cuidado para evitar que el comentario parezca una directiva de preprocesador de C,
para que no se interprete como tal. La forma más sencilla de evitar esto es poner espacios en blanco en
al frente de "#".

Si usa directivas de preprocesador para elegir una de las dos versiones de una función, use

#si... versión1
#else / * ... versión2 * /
#terminara si

y no

#si... versión1
#terminara si
#si... versión2
#terminara si

porque de otra manera xsubpp creerá que hizo una definición duplicada de la
función. Además, ponga una línea en blanco antes de # else / # endif para que no se vea como parte
del cuerpo de la función.

Con XS Con C + +
Si un nombre XSUB contiene "::", se considera un método C ++. El Perl generado
La función asumirá que su primer argumento es un puntero de objeto. El puntero de objeto
se almacenará en una variable llamada ESTO. El objeto debería haber sido creado por C ++ con
de la forma más nuevo() función y debe ser bendecido por Perl con la sv_setref_pv () macro. El
La bendición del objeto por Perl puede ser manejada por un typemap. Se muestra un ejemplo de mapa de tipos
al final de esta sección.

Si el tipo de retorno de XSUB incluye "estático", el método se considera estático.
método. Llamará a la función C ++ usando el clase :: método () sintaxis. Si el método es
no estático, la función se llamará usando ESTO->método() sintaxis.

Los siguientes ejemplos usarán la siguiente clase C ++.

color de clase {
pública:
color();
~ color ();
int azul ();
void set_blue (int);

privada:
int c_azul;
};

Los XSUB para azul() set_blue () Los métodos se definen con el nombre de la clase, pero el
El parámetro para el objeto (THIS, o "self") está implícito y no está listado.

int
color azul()

vacío
color :: set_blue (val)
valor internacional

Ambas funciones de Perl esperarán un objeto como primer parámetro. En el C ++ generado
codifique el objeto se llama "ESTO", y la llamada al método se realizará en este objeto.
Entonces en el código C ++ el azul() set_blue () Los métodos se llamarán así:

RETVAL = ESTO-> azul ();

ESTO-> set_blue (val);

También puede escribir un solo método get / set usando un argumento opcional:

int
color :: azul (val = NO_INIT)
valor internacional
PROTOTIPO $; $
CÓDIGO:
si (elementos> 1)
ESTO-> set_blue (val);
RETVAL = ESTO-> azul ();
SALIDA:
RETVALO

Si el nombre de la función es DESTRUIR entonces se llamará a la función "eliminar" de C ++ y "ESTO"
se le dará como parámetro. El código C ++ generado para

vacío
color :: DESTRUIR ()

se verá así:

color * ESTE = ...; // Inicializado como en typemap

borrar esto;

Si el nombre de la función es new entonces se llamará a la función "nueva" de C ++ para crear un
objeto dinámico de C ++. El XSUB esperará el nombre de la clase, que se mantendrá en una variable
llamado "CLASE", que se dará como primer argumento.

color *
color :: nuevo ()

El código C ++ generado llamará "nuevo".

RETVAL = nuevo color ();

El siguiente es un ejemplo de un mapa de tipos que podría usarse para este ejemplo de C ++.

MAPA DE TIPOS
color * O_OBJECT

SALIDA
# El objeto Perl está bendecido en 'CLASS', que debería ser un
# char * que tiene el nombre del paquete para la bendición.
O_OBJETO
sv_setref_pv ($ arg, CLASE, (vacío *) $ var);

ENTRADA
O_OBJETO
si (sv_isobject ($ arg) && (SvTYPE (SvRV ($ arg)) == SVt_PVMG))
$ var = ($ tipo) SvIV ((SV *) SvRV ($ arg));
más{
warn ("$ {Paquete} :: $ nombre_func () -".
"$ var no es una referencia SV bendita");
XSRETURN_UNDEF;
}

Fácil de usar Estrategia
Al diseñar una interfaz entre Perl y una biblioteca C, una traducción directa de C a
XS (como el creado por "h2xs -x") suele ser suficiente. Sin embargo, a veces la interfaz
se verá muy parecido a C y ocasionalmente no intuitivo, especialmente cuando la función C
modifica uno de sus parámetros, o devuelve un error en banda (como en "valores de retorno negativos
significa fallo "). En los casos en que el programador desee crear una interfaz más similar a Perl
la siguiente estrategia puede ayudar a identificar las partes más críticas de la interfaz.

Identificar las funciones C con parámetros de entrada / salida o salida. Los XSUB para estos
Las funciones pueden devolver listas a Perl.

Identifique las funciones C que usan información dentro de la banda como una indicación de falla. Que puede
ser candidatos a devolver undef o una lista vacía en caso de falla. Si la falla puede ser
detectado sin una llamada a la función C, es posible que desee utilizar una sección INIT: para informar
la falla. Para fallas detectables después de que la función C regresa, es posible que desee usar un
POSTCALL: sección para procesar el fallo. En casos más complicados, use CODE: o PPCODE:
.

Si muchas funciones usan la misma indicación de falla basada en el valor de retorno, es posible que desee
para crear un typedef especial para manejar esta situación. Poner

typedef int negativo_es_fallo;

cerca del comienzo del archivo XS, y cree una entrada de mapa de tipos de SALIDA para
"negative_is_failure", que convierte los valores negativos en "indef", o tal vez croar()s. Después
este el valor de retorno del tipo "negative_is_failure" creará una interfaz más similar a Perl.

Identificar qué valores son utilizados solo por las funciones C y XSUB en sí mismas, por ejemplo, cuando un
El parámetro de una función debe ser el contenido de una variable global. Si Perl no necesita
para acceder al contenido del valor, puede que no sea necesario proporcionar una traducción
para ese valor de C a Perl.

Identifique los punteros en las listas de parámetros de la función C y devuelva los valores. Algunos consejos
pueden usarse para implementar parámetros de entrada / salida o salida, pueden manejarse en XS con
el operador unario "&" y, posiblemente, utilizando la palabra clave NO_INIT. Algunos otros lo harán
requieren el manejo de tipos como "int *", y es necesario decidir qué Perl es útil
la traducción servirá en tal caso. Cuando la semántica es clara, es recomendable poner
la traducción a un archivo de mapa de tipos.

Identifica las estructuras utilizadas por las funciones C. En muchos casos, puede resultar útil utilizar
el typemap T_PTROBJ para estas estructuras para que puedan ser manipuladas por Perl como benditas
objetos. (Esto se gestiona automáticamente mediante "h2xs -x").

Si se utiliza el mismo tipo de C en varios contextos diferentes que requieren diferentes
traducciones, "typedef" varios tipos nuevos asignados a este tipo C y crear
mapa tipográfico entradas para estos nuevos tipos. Utilice estos tipos en declaraciones de tipo de retorno y
parámetros a XSUB.

Perl Objetos Y C Estructuras
Cuando se trata de estructuras C, se debe seleccionar T_PTROBJ or T_PTRREF para el XS
escribe. Ambos tipos están diseñados para manejar punteros a objetos complejos. El tipo T_PTRREF
permitirá que el objeto Perl no sea bendecido mientras que el tipo T_PTROBJ requiere que el
objeto sea bendecido. Al usar T_PTROBJ uno puede lograr una forma de verificación de tipo porque el
XSUB intentará verificar que el objeto Perl sea del tipo esperado.

El siguiente código XS muestra el getnetconfigent () función que se utiliza con ONC + TIRPC.
El proyecto getnetconfigent () La función devolverá un puntero a una estructura C y tiene la C
prototipo que se muestra a continuación. El ejemplo demostrará cómo el puntero C se convertirá en un Perl.
referencia. Perl considerará que esta referencia es un indicador de un objeto bendecido y
intente llamar a un destructor para el objeto. Se proporcionará un destructor en el XS
fuente para liberar la memoria utilizada por getnetconfigent (). Los destructores en XS pueden ser creados por
especificando una función XSUB cuyo nombre termina con la palabra DESTRUIR. Los destructores XS pueden ser
utilizado para liberar memoria que puede haber sido malloc'd por otro XSUB.

struct netconfig * getnetconfigent (const char * netid);

Se creará un "typedef" para "struct netconfig". El objeto Perl será bendecido en un
clase que coincida con el nombre del tipo C, con la etiqueta "Ptr" adjunta, y el nombre debe
no tener espacios incrustados si será un nombre de paquete de Perl. El destructor se colocará
en una clase correspondiente a la clase del objeto y la palabra clave PREFIX se utilizará para
recorta el nombre a la palabra DESTROY como espera Perl.

typedef estructura netconfig Netconfig;

MÓDULO = PAQUETE RPC = RPC

Configuración de red *
getnetconfigent (netid)
char * netid

MÓDULO = PAQUETE RPC = NetconfigPtr PREFIX = rpcb_

vacío
rpcb_DESTROY (netconf)
Netconfig * netconf
CÓDIGO:
printf ("Ahora en NetconfigPtr :: DESTROY \ n");
gratis (netconf);

Este ejemplo requiere la siguiente entrada de mapa de tipos. Consulte perlxstypemap para más
información sobre cómo agregar nuevos tipos de mapas para una extensión.

MAPA DE TIPOS
Configuración de red * T_PTROBJ

Este ejemplo se utilizará con las siguientes declaraciones de Perl.

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

Cuando Perl destruye el objeto al que hace referencia $ netconf, enviará el objeto al
incluida la función XSUB DESTROY. Perl no puede determinar, y no le importa, que este
El objeto es una estructura C y no un objeto Perl. En este sentido, no hay diferencia entre
el objeto creado por el getnetconfigent () XSUB y un objeto creado por un Perl normal
subrutina.

Sin peligro Almacenamiento Estático Respaldo de in XS
A partir de Perl 5.8, se ha definido un marco macro para permitir que los datos estáticos sean
almacenados de forma segura en módulos XS a los que se accederá desde un Perl multiproceso.

Aunque se diseñaron principalmente para su uso con Perl multiproceso, las macros se han
diseñado para que también funcionen con Perl sin subprocesos.

Por lo tanto, se recomienda encarecidamente que estas macros sean utilizadas por todos los módulos XS que hacen
uso de datos estáticos.

La forma más sencilla de obtener un conjunto de plantillas de macros para usar es especificando "-g"
("--global") opción con h2xs (ver h2xs).

A continuación se muestra un módulo de ejemplo que hace uso de las macros.

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

/ * Datos globales * /

#define MY_CXT_KEY "BlindMice :: _ guts" XS_VERSION

typedef struct {
int cuenta;
nombre de char [3] [100];
} mi_cxt_t;

START_MY_CXT

MÓDULO = BlindMice PAQUETE = BlindMice

BOTA:
{
MI_CXT_INIT;
MY_CXT.cuenta = 0;
strcpy (MY_CXT.name [0], "Ninguno");
strcpy (MY_CXT.name [1], "Ninguno");
strcpy (MY_CXT.name [2], "Ninguno");
}

int
newMouse (char * nombre)
PREINICIO:
dMY_CXT;
CÓDIGO:
if (MY_CXT.count> = 3) {
advertir ("Ya tengo 3 ratones ciegos");
REVALO = 0;
}
else {
RETVAL = ++ MY_CXT.cuenta;
strcpy(MI_CXT.nombre[MI_CXT.cuenta - 1], nombre);
}
SALIDA:
RETVALO

carácter *
get_mouse_name(índice)
int índice
PREINICIO:
dMY_CXT;
CÓDIGO:
if (índice > MY_CXT.count)
croar ("Solo hay 3 ratones ciegos");
más
RETVAL = MI_CXT.nombre[índice - 1];
SALIDA:
RETVALO

vacío
CLON(...)
CÓDIGO:
MI_CXT_CLONE;

MI_CXT REFERENCIA

MI_CXT_CLAVE
Esta macro se utiliza para definir una clave única para hacer referencia a los datos estáticos de un XS
módulo. El esquema de nomenclatura sugerido, como lo usa h2xs, es usar una cadena que
consta del nombre del módulo, la cadena "::_guts" y el número de versión del módulo.

#define MY_CXT_KEY "Mi Módulo::_guts" XS_VERSION

typedef mi_cxt_t
Esta estructura typedef deben siempre se llamará "my_cxt_t". Las otras macros "CXT*" asumen
la existencia del nombre typedef "my_cxt_t".

Declare un typedef llamado "my_cxt_t" que es una estructura que contiene todos los datos
que necesita ser intérprete-local.

typedef struct {
int algún_valor;
} mi_cxt_t;

START_MY_CXT
Coloque siempre la macro START_MY_CXT directamente después de la declaración de "my_cxt_t".

MI_CXT_INIT
La macro MY_CXT_INIT inicializa el almacenamiento para la estructura "my_cxt_t".

It deben ser llamado exactamente una vez, normalmente en una sección BOOT:. Si estás manteniendo
múltiples intérpretes, debe llamarse una vez en cada instancia de intérprete, excepto
para intérpretes clonados de los existentes. (Pero vea "MY_CXT_CLONE" a continuación).

dMY_CXT
Utilice la macro dMY_CXT (una declaración) en todas las funciones que acceden a MY_CXT.

MI_CXT
Utilice la macro MY_CXT para acceder a los miembros de la estructura "my_cxt_t". Por ejemplo, si
"mi_cxt_t" es

typedef struct {
índice int;
} mi_cxt_t;

luego use esto para acceder al miembro "índice"

dMY_CXT;
MI_CXT.índice = 2;

aMY_CXT/pMY_CXT
"dMY_CXT" puede ser bastante costoso de calcular y para evitar la sobrecarga de invocar
en cada función es posible pasar la declaración a otras funciones usando
las macros "aMY_CXT"/"pMY_CXT", por ejemplo

vacío sub1() {
dMY_CXT;
MI_CXT.índice = 1;
sub2(aMY_CXT);
}

vacío sub2 (pMY_CXT) {
MI_CXT.índice = 2;
}

Análogamente a "pTHX", existen formas equivalentes para cuando la macro es la primera o
último en varios argumentos, donde un guión bajo representa una coma, es decir, "_aMY_CXT",
"aMY_CXT_", "_pMY_CXT" y "pMY_CXT_".

MI_CXT_CLONE
De forma predeterminada, cuando se crea un nuevo intérprete como copia de uno existente (por ejemplo, a través de
"threads->create()"), ambos intérpretes comparten la misma estructura física my_cxt_t.
Llamar a "MY_CXT_CLONE" (típicamente a través de la función "CLONE()" del paquete), provoca un
copia byte por byte de la estructura a tomar, y cualquier dMY_CXT futuro causará
la copia a la que se accederá en su lugar.

MI_CXT_INIT_INTERP(mi_perl)
dMY_CXT_INTERP(mi_perl)
Estas son versiones de las macros que toman un intérprete explícito como argumento.

Tenga en cuenta que estas macros solo funcionarán juntas dentro del mismo archivo fuente; eso es un
dMY_CTX en un archivo fuente accederá a una estructura diferente que dMY_CTX en otro
archivo fuente.

Consciente de subprocesos te las interfaces
A partir de Perl 5.8, en el nivel C/C++, Perl sabe cómo envolver interfaces de sistema/biblioteca
que tienen versiones compatibles con subprocesos (p. ej. obtenerpwent_r()) en macros frontend (p. ej. getpwent ())
que manejen correctamente la interacción multiproceso con el intérprete de Perl. Esta voluntad
ocurrir de forma transparente, lo único que debe hacer es crear una instancia de un intérprete de Perl.

Este ajuste ocurre siempre cuando se compila el código fuente principal de Perl (se define PERL_CORE) o el
Extensiones principales de Perl (se define PERL_EXT). Al compilar código XS fuera del núcleo de Perl
el envoltorio no se produce. Tenga en cuenta, sin embargo, que mezclar las formas _r (como Perl
compilado para la operación de subprocesos múltiples funcionará) y las formas _r-less tampoco son buenas
definido (los resultados inconsistentes, la corrupción de datos o incluso los bloqueos son más probables), ni
¿Es muy portátil?

EJEMPLOS


Archivo "RPC.xs": interfaz para algunas funciones de biblioteca de enlace ONC+ RPC.

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

#incluir

typedef estructura netconfig Netconfig;

MÓDULO = PAQUETE RPC = RPC

VS *
rpcb_gettime(host="localhost")
char * anfitrión
PREINICIO:
tiempo_t tiempop;
CÓDIGO:
ST(0) = sv_newmortal ();
if (rpcb_gettime (host y timep))
sv_setnv ( ST(0), (doble) tiempop );

Configuración de red *
getnetconfigent(netid="udp")
char * netid

MÓDULO = PAQUETE RPC = NetconfigPtr PREFIX = rpcb_

vacío
rpcb_DESTROY (netconf)
Netconfig * netconf
CÓDIGO:
printf("NetconfigPtr::DESTROY\n");
gratis (netconf);

Archivo "typemap": mapa de tipos personalizado para RPC.xs. (cf. perlxstypemap)

MAPA DE TIPOS
Configuración de red * T_PTROBJ

Archivo "RPC.pm": Módulo Perl para la extensión RPC.

paquete RPC;

requiera exportador;
requieren DynaLoader;
@ISA = qw (Exportador DynaLoader);
@EXPORTAR = qw(rpcb_gettime getnetconfigent);

RPC de arranque;
1;

Archivo "rpctest.pl": programa de prueba de Perl para la extensión RPC.

utilizar RPC;

$netconf = getnetconf ();
$a = rpcb_gettime();
imprimir "hora = $a\n";
imprimir "netconf = $netconf\n";

$netconf = getnetconfigent("tcp");
$a = rpcb_gettime("álamo");
imprimir "hora = $a\n";
imprimir "netconf = $netconf\n";

AVISOS


El código XS tiene acceso completo a las llamadas del sistema, incluidas las funciones de la biblioteca C. Tiene pues la
capacidad de interferir con las cosas que el núcleo de Perl u otros módulos han configurado,
como manejadores de señales o manejadores de archivos. Podría alterar la memoria, o cualquier número de
cosas dañinas. no

Algunos módulos tienen un bucle de eventos, esperando la entrada del usuario. Es muy poco probable que dos
tales módulos funcionarían adecuadamente juntos en una sola aplicación Perl.

En general, el intérprete de perl se ve a sí mismo como el centro del universo en la medida en que
El programa Perl va. El código XS se ve como un compañero de ayuda para lograr cosas que perl
no lo hace, o no lo hace lo suficientemente rápido, pero siempre subordinado a perl. El código XS más cercano
se adhiere a este modelo, es menos probable que ocurran conflictos.

Un área donde ha habido conflicto es con respecto a los locales C. (Véase perlocale.)
perl, con una excepción y a menos que se indique lo contrario, configura la configuración regional subyacente
el programa se está ejecutando en la configuración regional que se le pasó desde el entorno. Esto es un
diferencia importante de un programa de lenguaje C genérico, donde la configuración regional subyacente es el
Configuración regional "C" a menos que el programa la cambie. A partir de v5.20, esta configuración regional subyacente es
completamente oculto del código perl puro fuera del alcance léxico de "usar configuración regional" excepto por
un par de llamadas de función en el módulo POSIX que necesariamente lo usan. Pero el
configuración regional subyacente, con esa única excepción que está expuesta al código XS, lo que afecta a toda la biblioteca C
rutinas cuyo comportamiento depende de la configuración regional. Es mejor que su código XS no asuma que el
la configuración regional subyacente es "C". La excepción es la categoría de configuración regional "LC_NUMERIC" y la
la razón por la que es una excepción es que la experiencia ha demostrado que puede ser problemático para XS
código, mientras que no hemos tenido informes de problemas con las otras categorías locales. Y
la razón por la que esta categoría es problemática es que el carácter utilizado como decimal
el punto puede variar. Muchos idiomas europeos usan una coma, mientras que el inglés y, por lo tanto, Perl son
esperando un punto (U+002E: PUNTO COMPLETO). Muchos módulos solo pueden manejar el carácter radix
ser un punto, por lo que Perl intenta que así sea. Hasta Perl v5.20, el intento fue
simplemente para establecer "LC_NUMERIC" en el inicio en la configuración regional "C". Ningún setlocale () de otra manera
lo cambiaría; esto causó algunas fallas. Por lo tanto, a partir de v5.22, perl intenta
mantenga "LC_NUMERIC" siempre establecido en "C" para el código XS.

Para resumir, esto es lo que puede esperar y cómo manejar las configuraciones regionales en el código XS:

Código XS que no reconoce la configuración regional
Tenga en cuenta que incluso si cree que su código no tiene en cuenta la configuración regional, puede llamar a un C
función de biblioteca que es. Con suerte, la página de manual para tal función indicará
esa dependencia, pero la documentación es imperfecta.

La configuración regional actual está expuesta al código XS excepto posiblemente "LC_NUMERIC" (explicado en
el párrafo siguiente). No ha habido reportes de problemas con los otros
categorías. Perl inicializa las cosas en el inicio para que la configuración regional actual sea la
que está indicado por el entorno del usuario en vigor en ese momento. Ver
"MEDIO AMBIENTE" en perlocale.

Sin embargo, hasta la versión 5.20, Perl inicializaba las cosas al inicio para que "LC_NUMERIC"
se configuró en la configuración regional "C". Pero si algún código en algún lugar lo cambiara, se quedaría
cambió. Esto significa que su módulo no puede contar con que "LC_NUMERIC" sea algo en
particular, y no puede esperar que los números de punto flotante (incluidas las cadenas de versión)
tienen puntos en ellos. Si no permite un no-punto, su código podría romperse si alguien
en cualquier lugar cambió la configuración regional. Por esta razón, v5.22 cambió el comportamiento para que Perl
intenta mantener "LC_NUMERIC" en la configuración regional "C", excepto alrededor de las operaciones internas
donde debería estar otra cosa. El código XS que se porta mal siempre podrá cambiar
la configuración regional de todos modos, pero la instancia más común de esto se verifica y se maneja.

Código XS compatible con la configuración regional
Si se desea la configuración regional del entorno del usuario, no debería haber necesidad de XS
código para establecer la configuración regional excepto "LC_NUMERIC", ya que Perl ya lo ha configurado. XS
El código debe evitar cambiar la configuración regional, ya que puede afectar negativamente a otros, no relacionados,
código y puede no ser seguro para subprocesos. Sin embargo, algunas bibliotecas alienígenas que pueden llamarse no
configurarlo, como "Gtk". Esto puede causar problemas para el núcleo de perl y otros módulos.
A partir de v5.20.1, llamar a la función sincronización_local() de XS debería ser suficiente
para evitar la mayoría de estos problemas. Antes de esto, necesita una instrucción Perl pura que
Haz esto:

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

En el caso de que su código XS necesite la configuración regional "LC_NUMERIC" subyacente, hay
macros disponibles para acceder a esto; consulte "Funciones y macros relacionadas con la configuración regional" en perlapi.

XS VERSION


Este documento cubre las funciones admitidas por "ExtUtils::ParseXS" (también conocido como "xsubpp")
3.13_01.

Use perlxs en línea usando los servicios de onworks.net


Servidores y estaciones de trabajo gratuitos

Descargar aplicaciones de Windows y Linux

Comandos de Linux

Ad