InglêsFrancêsEspanhol

favicon do OnWorks

perlxs - Online na nuvem

Execute perlxs no provedor de hospedagem gratuita OnWorks no Ubuntu Online, Fedora Online, emulador online do Windows ou emulador online do MAC OS

Este é o comando perlxs que pode ser executado no provedor de hospedagem gratuita OnWorks usando uma de nossas várias estações de trabalho online gratuitas, como Ubuntu Online, Fedora Online, emulador online do Windows ou emulador online do MAC OS

PROGRAMA:

NOME


perlxs - manual de referência da linguagem XS

DESCRIÇÃO


Introdução
XS é um formato de arquivo de descrição de interface usado para criar uma interface de extensão entre
Perl e código C (ou uma biblioteca C) que se deseja usar com Perl. A interface XS é
combinado com a biblioteca para criar uma nova biblioteca que pode ser dinamicamente
carregado ou vinculado estaticamente ao perl. A descrição da interface XS é escrita no XS
linguagem e é o componente principal da interface de extensão Perl.

Antes de escrever XS, leia a seção "CAVEATS" abaixo.

An XSUB forma a unidade básica da interface XS. Após a compilação pelo xsubpp
compilador, cada XSUB equivale a uma definição de função C que fornecerá a cola entre
Convenções de chamada Perl e convenções de chamada C.

O código cola puxa os argumentos da pilha Perl, converte esses valores Perl para o
formatos esperados por uma função C, chame esta função C, transfere os valores de retorno do
Função C de volta para Perl. Os valores de retorno aqui podem ser um valor de retorno C convencional ou qualquer C
argumentos de função que podem servir como parâmetros de saída. Esses valores de retorno podem ser passados
de volta ao Perl colocando-os na pilha Perl ou modificando os argumentos
fornecido do lado Perl.

A descrição acima é uma visão um tanto simplificada do que realmente acontece. Como o Perl permite mais
convenções de chamada flexíveis do que C, XSUBs podem fazer muito mais na prática, como verificar
parâmetros de entrada para validade, lançando exceções (ou retornando undef / lista vazia) se o
valor de retorno da função C indica falha, chamando diferentes funções C com base em
números e tipos de argumentos, fornecendo uma interface orientada a objetos, etc.

Claro, pode-se escrever esse código de cola diretamente em C. No entanto, isso seria um tedioso
tarefa, especialmente se for necessário escrever cola para várias funções C, e / ou uma não é
familiarizado o suficiente com a disciplina de pilha Perl e outros arcanos semelhantes. XS vem para o
resgate aqui: em vez de escrever este código C colante à mão, pode-se escrever mais
taquigrafia concisa descrição do que deve ser feito pela cola, e deixe o compilador XS
xsubpp lidar com o resto.

A linguagem XS permite descrever o mapeamento entre como a rotina C é usada, e
como a rotina Perl correspondente é usada. Também permite a criação de rotinas Perl
que são traduzidos diretamente para o código C e que não estão relacionados a um código C pré-existente
função. Nos casos em que a interface C coincide com a interface Perl, o XSUB
declaração é quase idêntica a uma declaração de uma função C (no estilo K&R). Em tal
circunstâncias, existe outra ferramenta chamada "h2xs" que é capaz de traduzir um C inteiro
arquivo de cabeçalho em um arquivo XS correspondente que fornecerá cola para as funções / macros
descrito no arquivo de cabeçalho.

O compilador XS é chamado xsubpp. Este compilador cria as construções necessárias para permitir
um XSUB manipula valores Perl e cria a cola necessária para permitir que Perl chame o XSUB.
O compilador usa mapas de tipos para determinar como mapear os parâmetros da função C e os valores de saída
para valores Perl e vice-versa. O mapa de tipos padrão (que vem com o Perl) lida com muitos
Tipos C. Um mapa de tipo suplementar também pode ser necessário para lidar com quaisquer estruturas especiais e
tipos para a biblioteca que está sendo vinculada. Para obter mais informações sobre mapas de tipos, consulte perlxstypemap.

Um arquivo no formato XS começa com uma seção da linguagem C que vai até o primeiro "MODULE ="
diretiva. Outras diretivas XS e definições XSUB podem seguir esta linha. O idioma"
usado nesta parte do arquivo é geralmente referido como a linguagem XS. xsubpp
reconhece e pula POD (ver perlpod) em ambas as seções de linguagem C e XS, que
permite que o arquivo XS contenha documentação incorporada.

Veja perlxstut para um tutorial sobre todo o processo de criação de extensão.

Nota: Para algumas extensões, o sistema SWIG de Dave Beazley pode fornecer um significativamente mais
mecanismo conveniente para criar o código de colagem de extensão. Verhttp://www.swig.org/> para
Mais Informações.

On O Road
Muitos dos exemplos a seguir se concentrarão na criação de uma interface entre Perl
e as funções de biblioteca de ligação ONC + RPC. O rpcb_gettime () função é usada para
demonstrar muitos recursos da linguagem XS. Esta função possui dois parâmetros; o primeiro
é um parâmetro de entrada e o segundo é um parâmetro de saída. A função também retorna um
valor de status.

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

A partir de C, esta função será chamada com as seguintes instruções.

#incluir
status bool_t;
tempo_t tempop;
status = rpcb_gettime ("localhost", & timep);

Se um XSUB for criado para oferecer uma tradução direta entre esta função e Perl, então
este XSUB será usado a partir do Perl com o código a seguir. O $ status e $ timep
variáveis ​​conterão a saída da função.

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

O seguinte arquivo XS mostra uma sub-rotina XS, ou XSUB, que demonstra um possível
interface para o rpcb_gettime () função. Este XSUB representa uma tradução direta
entre C e Perl e, portanto, preserva a interface até mesmo do Perl. Este XSUB será
chamado de Perl com o uso mostrado acima. Observe que os três primeiros #include
instruções, para "EXTERN.h", "perl.h" e "XSUB.h", sempre estarão presentes no
início de um arquivo XS. Esta abordagem e outras serão expandidas posteriormente neste
documento. Um #define para "PERL_NO_GET_CONTEXT" deve estar presente para buscar o intérprete
contexto de forma mais eficiente, consulte perlguts para obter detalhes.

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

MÓDULO = PACOTE RPC = RPC

bool_t
rpcb_gettime (host, timep)
char * host
time_t & timep
SAÍDA:
cronômetro

Qualquer extensão para Perl, incluindo aquelas contendo XSUBs, deve ter um módulo Perl para
serve como bootstrap que puxa a extensão para o Perl. Este módulo irá exportar o
funções e variáveis ​​da extensão para o programa Perl e fará com que a extensão
XSUBs a serem vinculados ao Perl. O módulo a seguir será usado para a maioria dos exemplos
neste documento e deve ser usado a partir do Perl com o comando "use" conforme mostrado anteriormente.
Os módulos Perl são explicados com mais detalhes posteriormente neste documento.

pacote RPC;

exigir exportador;
requer DynaLoader;
@ISA = qw (Exportador DynaLoader);
@EXPORT = qw (rpcb_gettime);

RPC de inicialização;
1;

Ao longo deste documento, uma variedade de interfaces para o rpcb_gettime () XSUB será
explorado. Os XSUBs tomarão seus parâmetros em ordens diferentes ou tomarão diferentes
número de parâmetros. Em cada caso, o XSUB é uma abstração entre o Perl e o real
C rpcb_gettime () função, e o XSUB deve sempre garantir que o real rpcb_gettime ()
função é chamada com os parâmetros corretos. Esta abstração permitirá que o
programador para criar uma interface mais parecida com Perl para a função C.

O Anatomia of an XSUB
Os XSUBs mais simples consistem em 3 partes: uma descrição do valor de retorno, o nome do
Rotina XSUB e os nomes de seus argumentos, e uma descrição dos tipos ou formatos do
argumentos.

O seguinte XSUB permite que um programa Perl acesse uma função de biblioteca C chamada sem (). O
XSUB irá imitar a função C que recebe um único argumento e retorna um único valor.

duplo
sin (x)
duplo x

Opcionalmente, pode-se mesclar a descrição dos tipos e a lista de nomes de argumentos,
reescrevendo isso como

duplo
sin (duplo x)

Isso faz com que este XSUB seja semelhante a uma declaração ANSI C. Um ponto e vírgula opcional é
permitido após a lista de argumentos, como em

duplo
sin (duplo x);

Parâmetros com tipos de ponteiro C podem ter diferentes semânticas: funções C com semelhantes
declarações

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

são usados ​​de maneira absolutamente incompatível. Os parâmetros para essas funções podem ser
descrito xsubpp como isso:

caractere * s
char & c

Ambas as declarações XS correspondem ao tipo C "char *", mas têm diferentes
semântica, consulte "The & Unary Operator".

É conveniente pensar que o operador de indireção "*" deve ser considerado como uma parte
do tipo e o operador de endereço "&" deve ser considerado parte da variável. Ver
perlxstypemap para obter mais informações sobre como lidar com qualificadores e operadores unários em tipos C.

O nome da função e o tipo de retorno devem ser colocados em linhas separadas e devem ser alinhados
ajustado à esquerda.

INCORRETO CORRETO

duplo sin (x) duplo
duplo x sin (x)
duplo x

O resto da descrição da função pode ser recuado ou ajustado à esquerda. A seguir
o exemplo mostra uma função com seu corpo ajustado à esquerda. A maioria dos exemplos neste documento irá
recue o corpo para melhor legibilidade.

CORRIGIR

duplo
sin (x)
duplo x

XSUBs mais complicados podem conter muitas outras seções. Cada seção de um XSUB começa
com a palavra-chave correspondente, como INIT: ou CLEANUP :. No entanto, as duas primeiras linhas
de um XSUB sempre contém os mesmos dados: descrições do tipo de retorno e os nomes de
a função e seus parâmetros. O que quer que se siga imediatamente é considerado
uma seção INPUT: a menos que explicitamente marcada com outra palavra-chave. (Veja "A ENTRADA:
Palavra-chave ".)

Uma seção XSUB continua até que outra palavra-chave de início de seção seja encontrada.

O Argumento Pilha
A pilha de argumentos Perl é usada para armazenar os valores que são enviados como parâmetros para o
XSUB e para armazenar os valores de retorno de XSUB. Na realidade, todas as funções Perl (incluindo
não-XSUB) mantêm seus valores nesta pilha ao mesmo tempo, cada um limitado ao seu
gama de posições na pilha. Neste documento, a primeira posição na pilha que
pertence à função ativa será referido como posição 0 para essa função.

XSUBs referem-se aos seus argumentos de pilha com a macro ST (x), Onde x refere-se a uma posição em
este XSUB é parte da pilha. A posição 0 para essa função seria conhecida pelo XSUB como
ST(0). Os parâmetros de entrada e valores de retorno de saída do XSUB sempre começam em ST(0).
Para muitos casos simples, o xsubpp compilador irá gerar o código necessário para lidar com o
pilha de argumentos incorporando fragmentos de código encontrados nos mapas de tipos. Em casos mais complexos
o programador deve fornecer o código.

O RETIRADA Variável
A variável RETVAL é uma variável C especial que é declarada automaticamente para você. O C
tipo de RETVAL corresponde ao tipo de retorno da função de biblioteca C. O xsubpp compilador
irá declarar esta variável em cada XSUB com tipo de retorno não "nulo". Por padrão, o
A função C gerada usará RETVAL para manter o valor de retorno da função da biblioteca C
sendo chamado. Em casos simples, o valor de RETVAL será colocado em ST(0) do argumento
pilha onde pode ser recebido por Perl como o valor de retorno do XSUB.

Se o XSUB tiver um tipo de retorno "void", o compilador não irá declarar um RETVAL
variável para essa função. Ao usar um PPCODE: seção sem manipulação do RETVAL
variável é necessária, a seção pode usar a manipulação direta da pilha para colocar os valores de saída
na pilha.

Se PPCODE: a diretiva não for usada, o valor de retorno "void" deve ser usado apenas para sub-rotinas
que não retornam um valor, até if CÓDIGO: é usada a diretiva que define ST(0) explicitamente.

Versões mais antigas deste documento recomendavam o uso de valor de retorno "nulo" em tais casos. Isto
foi descoberto que isso poderia levar a falhas de segurança nos casos em que XSUB era verdadeiramente "vazio". Isto
a prática agora está obsoleta e pode não ser suportada em alguma versão futura. Use o
valor de retorno "SV *" em tais casos. (Atualmente "xsubpp" contém algum código heurístico que
tenta eliminar a ambigüidade entre as funções "verdadeiramente vazio" e "prática antiga declarada como vazio".
Portanto, seu código está à mercê dessa heurística, a menos que você use "SV *" como valor de retorno.)

Voltando VVs, AV e ATs NFT`s RETIRADA
Quando você está usando RETVAL para retornar um "SV *", há alguma mágica acontecendo por trás do
cenas que devem ser mencionadas. Quando você está manipulando a pilha de argumentos usando o
Na macro ST (x), por exemplo, normalmente é necessário prestar atenção especial às contagens de referência.
(Para obter mais informações sobre contagens de referência, consulte perlguts.) Para tornar sua vida mais fácil, o mapa de tipos
O arquivo torna "RETVAL" mortal automaticamente quando você retorna um "SV *". Então, o
os dois XSUBs a seguir são mais ou menos equivalentes:

anular
alfa()
CÓDIGO PP:
ST(0) = newSVpv ("Hello World", 0);
sv_2mortal (ST(0));
XSRETURN(1);

SV *
beta()
CÓDIGO:
RETVAL = newSVpv ("Hello World", 0);
SAÍDA:
RETIRADA

Isso é muito útil, pois geralmente melhora a legibilidade. Embora isso funcione bem para um "SV
* ", infelizmente não é tão fácil ter" AV * "ou" HV * "como valor de retorno. rede de apoio social
ser capaz de escrever:

AV*
array ()
CÓDIGO:
RETVAL = newAV ();
/ * fazer algo com RETVAL * /
SAÍDA:
RETIRADA

Mas, devido a um bug não corrigível (consertá-lo quebraria muitos módulos CPAN existentes) no
arquivo typemap, a contagem de referência do "AV *" não é diminuída corretamente. Então, o
acima de XSUB vazaria memória sempre que fosse chamado. O mesmo problema existe para "HV
* "," CV * "e" SVREF "(que indica uma referência escalar, não um" SV * "geral). Em XS
código em perls começando com perl 5.16, você pode substituir os mapas de tipos para qualquer um destes
tipos com uma versão que possui tratamento adequado de refcounts. Em sua seção "TYPEMAP", faça

AV * T_AVREF_REFCOUNT_FIXED

para obter a variante reparada. Para compatibilidade com versões anteriores do perl, você
em vez disso, pode diminuir a contagem de referência manualmente quando você está retornando um dos
tipos mencionados acima usando "sv_2mortal":

AV*
array ()
CÓDIGO:
RETVAL = newAV ();
sv_2mortal ((SV *) RETVAL);
/ * fazer algo com RETVAL * /
SAÍDA:
RETIRADA

Lembre-se de que você não precisa fazer isso para um "SV *". A documentação de referência para todos
Os mapas de tipos principais podem ser encontrados em perlxstypemap.

O MÓDULO Palavra-chave
A palavra-chave MODULE é usada para iniciar o código XS e especificar o pacote do
funções que estão sendo definidas. Todo o texto que precede a primeira palavra-chave MODULE é
considerado código C e é passado para a saída com POD removido, mas de outra forma
intocado. Cada módulo XS terá uma função bootstrap que é usada para ligar os XSUBs
em Perl. O nome do pacote desta função de inicialização irá corresponder ao valor do último
Instrução MODULE nos arquivos de origem XS. O valor de MODULE deve permanecer sempre
constante no mesmo arquivo XS, embora isso não seja necessário.

O exemplo a seguir iniciará o código XS e colocará todas as funções em um pacote
denominado RPC.

MÓDULO = RPC

O PACKAGE Palavra-chave
Quando as funções em um arquivo de origem XS devem ser separadas em pacotes, o PACKAGE
palavra-chave deve ser usada. Esta palavra-chave é usada com a palavra-chave MODULE e deve seguir
imediatamente após quando usado.

MÓDULO = PACOTE RPC = RPC

[Código XS no pacote RPC]

MÓDULO = PACOTE RPC = RPCB

[Código XS no pacote RPCB]

MÓDULO = PACOTE RPC = RPC

[Código XS no pacote RPC]

O mesmo nome de pacote pode ser usado mais de uma vez, permitindo código não contíguo. Isto
é útil se você tiver um princípio de ordenação mais forte do que nomes de pacotes.

Embora esta palavra-chave seja opcional e, em alguns casos, forneça informações redundantes,
sempre deve ser usado. Esta palavra-chave irá garantir que os XSUBs apareçam no formato desejado
pacote.

O PREFIXO Palavra-chave
A palavra-chave PREFIX designa prefixos que devem ser removidos da função Perl
nomes. Se a função C é "rpcb_gettime ()" e o valor PREFIX é "rpcb_" então Perl
verá essa função como "gettime ()".

Esta palavra-chave deve seguir a palavra-chave PACKAGE quando usada. Se PACKAGE não for usado, então
PREFIX deve seguir a palavra-chave MODULE.

MÓDULO = RPC PREFIX = rpc_

MÓDULO = PACOTE RPC = PREFIXO RPCB = rpcb_

O SAÍDA: Palavra-chave
A palavra-chave OUTPUT: indica que certos parâmetros de função devem ser atualizados (novo
valores tornados visíveis para Perl) quando o XSUB termina ou que certos valores devem ser
retornou para a função Perl de chamada. Para funções simples que não têm CÓDIGO: ou
PPCODE: seção, como o sem () função acima, a variável RETVAL é automaticamente
designado como um valor de saída. Para funções mais complexas, o xsubpp o compilador vai precisar
ajudam a determinar quais variáveis ​​são variáveis ​​de saída.

Normalmente, esta palavra-chave será usada para complementar a palavra-chave CODE :. A variável RETVAL
não é reconhecido como uma variável de saída quando a palavra-chave CODE: está presente. A saída:
palavra-chave é usada nesta situação para dizer ao compilador que RETVAL é realmente uma saída
variável.

A palavra-chave OUTPUT: também pode ser usada para indicar que os parâmetros da função são produzidos
variáveis. Isso pode ser necessário quando um parâmetro foi modificado dentro da função
e o programador gostaria que a atualização fosse vista pelo Perl.

bool_t
rpcb_gettime (host, timep)
char * host
time_t & timep
SAÍDA:
cronômetro

A palavra-chave OUTPUT: também permitirá que um parâmetro de saída seja mapeado para uma peça correspondente
de código em vez de um mapa de tipos.

bool_t
rpcb_gettime (host, timep)
char * host
time_t & timep
SAÍDA:
timep sv_setnv (ST(1), (duplo) tempop);

xsubpp emite um "SvSETMAGIC ()" automático para todos os parâmetros na seção OUTPUT do
XSUB, exceto RETVAL. Este é o comportamento geralmente desejado, pois cuida de maneira adequada
invocando a magia 'set' nos parâmetros de saída (necessários para hash ou parâmetros de elemento de array
que deve ser criado se eles não existissem). Se por algum motivo, este comportamento não é
desejado, a seção OUTPUT pode conter uma linha "SETMAGIC: DISABLE" para desativá-lo para o
restante dos parâmetros na seção OUTPUT. Da mesma forma, "SETMAGIC: ENABLE" pode ser
usado para reativá-lo para o restante da seção OUTPUT. Veja perlguts para mais
detalhes sobre 'definir' magia.

O NO_OUTPUT Palavra-chave
O NO_OUTPUT pode ser colocado como o primeiro token do XSUB. Esta palavra-chave indica que
enquanto a sub-rotina C para a qual fornecemos uma interface tem um tipo de retorno não "nulo", o retorno
o valor desta sub-rotina C não deve ser retornado da sub-rotina Perl gerada.

Com esta palavra-chave presente "A Variável RETVAL" é criada, e na chamada gerada para
a sub-rotina a que esta variável é atribuída, mas o valor desta variável não vai
para ser usado no código gerado automaticamente.

Esta palavra-chave só faz sentido se "RETVAL" for acessado pelo usuário fornecido
código. É especialmente útil para fazer uma interface de função mais parecida com Perl, especialmente
quando o valor de retorno C é apenas um indicador de condição de erro. Por exemplo,

NO_OUTPUT interno
delete_file (char * name)
PÓS-CHAMADA:
if (RETVAL! = 0)
croak ("Erro% d ao excluir o arquivo '% s'", RETVAL, nome);

Aqui, a função XS gerada não retorna nada em caso de sucesso, e morrer () com uma
mensagem de erro significativa em caso de erro.

O CÓDIGO: Palavra-chave
Esta palavra-chave é usada em XSUBs mais complicados que requerem tratamento especial para o C
função. A variável RETVAL ainda está declarada, mas não será retornada a menos que seja
especificado na seção OUTPUT :.

O seguinte XSUB é para uma função C que requer tratamento especial de seus parâmetros.
O uso do Perl é fornecido primeiro.

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

O XSUB segue.

bool_t
rpcb_gettime (host, timep)
char * host
time_t timep
CÓDIGO:
RETVAL = rpcb_gettime (host, & timep);
SAÍDA:
cronômetro
RETIRADA

O INICIAR: Palavra-chave
A palavra-chave INIT: permite que a inicialização seja inserida no XSUB antes do compilador
gera a chamada para a função C. Ao contrário do CODE: palavra-chave acima, esta palavra-chave faz
não afeta a maneira como o compilador lida com RETVAL.

bool_t
rpcb_gettime (host, timep)
char * host
time_t & timep
INICIAR:
printf ("# Host é% s \ n", host);
SAÍDA:
cronômetro

Outro uso para a seção INIT: é verificar as condições prévias antes de fazer uma chamada para
a função C:

longo longo
lldiv (a, b)
muito tempo a
longo, longo b
INICIAR:
if (a == 0 && b == 0)
XSRETURN_UNDEF;
se (b == 0)
croak ("lldiv: não pode ser dividido por 0");

O NO_INIT Palavra-chave
A palavra-chave NO_INIT é usada para indicar que um parâmetro de função está sendo usado apenas como um
valor de saída. O xsubpp o compilador normalmente irá gerar código para ler os valores de todos
parâmetros de função da pilha de argumentos e atribuí-los a variáveis ​​C na entrada para
a função. NO_INIT dirá ao compilador que alguns parâmetros serão usados ​​para a saída
em vez de para entrada e que eles serão tratados antes que a função termine.

O exemplo a seguir mostra uma variação do rpcb_gettime () função. Esta função
usa a variável timep apenas como uma variável de saída e não se preocupa com o seu
conteúdos.

bool_t
rpcb_gettime (host, timep)
char * host
time_t & timep = NO_INIT
SAÍDA:
cronômetro

O MAPA DE TIPO: Palavra-chave
A partir do Perl 5.16, você pode incorporar mapas de tipos em seu código XS em vez de ou em
além de mapas de tipos em um arquivo separado. Vários desses mapas de tipos incorporados serão
processados ​​em ordem de aparecimento no código XS e como arquivos de tipo mapa locais,
precedência sobre o mapa de tipos padrão, os mapas de tipos embutidos podem sobrescrever os anteriores
definições de sub-rotinas TYPEMAP, INPUT e OUTPUT. A sintaxe para mapas de tipos incorporados é

TYPEMAP: <
... seu código de mapa de tipo aqui ...
AQUI

onde a palavra-chave "TYPEMAP" deve aparecer na primeira coluna de uma nova linha.

Consulte perlxstypemap para obter detalhes sobre como escrever mapas de tipos.

Inicializando função parâmetros
Os parâmetros da função C são normalmente inicializados com seus valores da pilha de argumentos
(que por sua vez contém os parâmetros que foram passados ​​para o XSUB do Perl). O
os mapas de tipos contêm os segmentos de código que são usados ​​para traduzir os valores Perl para o C
parâmetros. O programador, no entanto, tem permissão para substituir os mapas de tipos e fornecer
código de inicialização alternativo (ou adicional). O código de inicialização começa com o primeiro
"=", ";" ou "+" em uma linha na seção INPUT :. A única exceção acontece se este ";"
termina a linha, então este ";" é silenciosamente ignorado.

O código a seguir demonstra como fornecer código de inicialização para parâmetros de função.
O código de inicialização é avaliado entre aspas duplas pelo compilador antes de ser adicionado
para a saída, então qualquer coisa que deva ser interpretada literalmente [principalmente "$", "@" ou "\\"]
deve ser protegido com barras invertidas. As variáveis ​​$ var, $ arg e $ type podem ser usadas como em
mapas de tipos.

bool_t
rpcb_gettime (host, timep)
char * host = (char *) SvPV_nolen ($ arg);
time_t & timep = 0;
SAÍDA:
cronômetro

Isso não deve ser usado para fornecer valores padrão para parâmetros. Normalmente usaria
isso quando um parâmetro de função deve ser processado por outra função de biblioteca antes que possa
ser usado. Os parâmetros padrão são abordados na próxima seção.

Se a inicialização começa com "=", então é a saída na declaração para a entrada
variável, substituindo a inicialização fornecida pelo mapa de tipos. Se a inicialização
começa com ";" ou "+", então é executado depois que todas as variáveis ​​de entrada foram
declarado. No ";" caso a inicialização normalmente fornecida pelo mapa de tipos não seja
realizada. Para o caso "+", a declaração da variável incluirá o
inicialização do mapa de tipos. Uma variável global,% v, está disponível para os realmente raros
caso em que as informações de uma inicialização são necessárias em outra inicialização.

Aqui está um exemplo verdadeiramente obscuro:

bool_t
rpcb_gettime (host, timep)
time_t & timep; / * \ $ v {timep} = @ {[$ v {timep} = $ arg]} * /
char * host + SvOK ($ v {timep})? SvPV_nolen ($ arg): NULL;
SAÍDA:
cronômetro

A construção "\ $ v {timep} = @ {[$ v {timep} = $ arg]}" usada no exemplo acima tem um duplo
objetivo: primeiro, quando esta linha é processada por xsubpp, o snippet Perl "$ v {timep} = $ arg"
é avaliado. Em segundo lugar, o texto do snippet avaliado é enviado para o C gerado
(dentro de um comentário C)! Durante o processamento da linha "char * host", $ arg irá avaliar
para ST(0), e $ v {timep} avaliará como ST(1).

Padrão Parâmetro Valores
Os valores padrão para argumentos XSUB podem ser especificados colocando uma instrução de atribuição em
a lista de parâmetros. O valor padrão pode ser um número, uma string ou uma string especial
"NO_INIT". Os padrões sempre devem ser usados ​​apenas nos parâmetros mais à direita.

Para permitir o XSUB para rpcb_gettime () para ter um valor de host padrão, os parâmetros para o
XSUB pode ser reorganizado. O XSUB irá então chamar o real rpcb_gettime () funcionar com
os parâmetros na ordem correta. Este XSUB pode ser chamado de Perl com qualquer um dos
seguintes declarações:

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

$ status = rpcb_gettime ($ timep);

O XSUB será semelhante ao código a seguir. Um CODE: bloco é usado para chamar o
reais rpcb_gettime () função com os parâmetros na ordem correta para essa função.

bool_t
rpcb_gettime (timep, host = "localhost")
char * host
time_t timep = NO_INIT
CÓDIGO:
RETVAL = rpcb_gettime (host, & timep);
SAÍDA:
cronômetro
RETIRADA

O PRÉ-INICIAÇÃO: Palavra-chave
A palavra-chave PREINIT: permite que variáveis ​​extras sejam declaradas imediatamente antes ou depois do
declarações dos parâmetros da seção INPUT: são emitidas.

Se uma variável for declarada dentro de uma seção CODE: ela seguirá qualquer código de mapa de tipo que seja
emitido para os parâmetros de entrada. Isso pode resultar na declaração terminando após C
código, que é um erro de sintaxe C. Erros semelhantes podem acontecer com um tipo ";" - explícito ou
"+" - a inicialização de parâmetros do tipo é usada (consulte "Inicializando Parâmetros de Função").
Declarar essas variáveis ​​em uma seção INIT: não ajudará.

Nesses casos, para forçar uma variável adicional a ser declarada junto com as declarações
de outras variáveis, coloque a declaração em uma seção PREINIT :. O PREINIT: palavra-chave
pode ser usado uma ou mais vezes em um XSUB.

Os exemplos a seguir são equivalentes, mas se o código estiver usando mapas de tipos complexos, o
o primeiro exemplo é mais seguro.

bool_t
rpcb_gettime (timep)
time_t timep = NO_INIT
PRÉ-INICIAÇÃO:
char * host = "localhost";
CÓDIGO:
RETVAL = rpcb_gettime (host, & timep);
SAÍDA:
cronômetro
RETIRADA

Para este caso específico, uma palavra-chave INIT: geraria o mesmo código C que PREINIT:
palavra-chave. Outro exemplo correto, mas sujeito a erros:

bool_t
rpcb_gettime (timep)
time_t timep = NO_INIT
CÓDIGO:
char * host = "localhost";
RETVAL = rpcb_gettime (host, & timep);
SAÍDA:
cronômetro
RETIRADA

Outra maneira de declarar "host" é usar um bloco C na seção CODE:

bool_t
rpcb_gettime (timep)
time_t timep = NO_INIT
CÓDIGO:
{
char * host = "localhost";
RETVAL = rpcb_gettime (host, & timep);
}
SAÍDA:
cronômetro
RETIRADA

A capacidade de colocar declarações adicionais antes que as entradas do mapa de tipos sejam processadas é
muito útil nos casos em que as conversões de mapa de tipo manipulam algum estado global:

Meuobjeto
mutate (o)
PRÉ-INICIAÇÃO:
MeuEstado st = global_state;
ENTRADA:
MeuObjeto o;
LIMPAR:
reset_to (global_state, st);

Aqui, supomos que a conversão para "MyObject" na seção INPUT: e de MyObject quando
o processamento de RETVAL modificará uma variável global "global_state". Depois dessas conversões
são executados, restauramos o valor antigo de "global_state" (para evitar vazamentos de memória, para
exemplo).

Há outra maneira de trocar clareza por compactação: as seções de INPUT permitem a declaração de
Variáveis ​​C que não aparecem na lista de parâmetros de uma sub-rotina. Assim, o acima
código para mutate () pode ser reescrito como

Meuobjeto
mutate (o)
MeuEstado st = global_state;
MeuObjeto o;
LIMPAR:
reset_to (global_state, st);

e o código de rpcb_gettime () pode ser reescrito como

bool_t
rpcb_gettime (timep)
time_t timep = NO_INIT
char * host = "localhost";
C_ARGS:
host, & timep
SAÍDA:
cronômetro
RETIRADA

O ESCOPO: Palavra-chave
A palavra-chave SCOPE: permite que o escopo seja ativado para um XSUB específico. Se habilitado, o
XSUB invocará ENTER e LEAVE automaticamente.

Para suportar mapeamentos de tipo potencialmente complexos, se uma entrada de mapa de tipo usada por um XSUB contém
um comentário como "/ * escopo * /" então o escopo será automaticamente habilitado para esse XSUB.

Para habilitar o escopo:

ESCOPO: ENABLE

Para desativar o escopo:

ESCOPO: DESATIVAR

O ENTRADA: Palavra-chave
Os parâmetros do XSUB são geralmente avaliados imediatamente após entrar no XSUB. O
INPUT: a palavra-chave pode ser usada para forçar a avaliação desses parâmetros um pouco mais tarde. O
INPUT: a palavra-chave pode ser usada várias vezes em um XSUB e pode ser usada para listar um ou
mais variáveis ​​de entrada. Esta palavra-chave é usada com a palavra-chave PREINIT :.

O exemplo a seguir mostra como o parâmetro de entrada "timep" pode ser avaliado tarde, após um
PRÉ-INICIAL.

bool_t
rpcb_gettime (host, timep)
char * host
PRÉ-INICIAÇÃO:
tempo_t tt;
ENTRADA:
time_t timep
CÓDIGO:
RETVAL = rpcb_gettime (host, & tt);
tempop = tt;
SAÍDA:
cronômetro
RETIRADA

O próximo exemplo mostra cada parâmetro de entrada avaliado tardiamente.

bool_t
rpcb_gettime (host, timep)
PRÉ-INICIAÇÃO:
tempo_t tt;
ENTRADA:
char * host
PRÉ-INICIAÇÃO:
char * h;
ENTRADA:
time_t timep
CÓDIGO:
h = hospedeiro;
RETVAL = rpcb_gettime (h, & tt);
tempop = tt;
SAÍDA:
cronômetro
RETIRADA

Uma vez que as seções INPUT permitem a declaração de variáveis ​​C que não aparecem no parâmetro
lista de uma sub-rotina, pode ser encurtada para:

bool_t
rpcb_gettime (host, timep)
tempo_t tt;
char * host;
char * h = host;
tempo_t tempop;
CÓDIGO:
RETVAL = rpcb_gettime (h, & tt);
tempop = tt;
SAÍDA:
cronômetro
RETIRADA

(Usamos nosso conhecimento de que a conversão de entrada para "char *" é "simples", portanto, "host"
é inicializado na linha de declaração, e nossa atribuição "h = host" também não é realizada
cedo. Caso contrário, seria necessário ter a atribuição "h = host" em um CODE: ou INIT:
seção.)

O IN / OUTLIST / IN_OUTLIST / OUT / IN_OUT Palavras-chave
Na lista de parâmetros para um XSUB, pode-se preceder os nomes dos parâmetros pelo
Palavras-chave "IN" / "OUTLIST" / "IN_OUTLIST" / "OUT" / "IN_OUT". A palavra-chave "IN" é o padrão, o
outras palavras-chave indicam como a interface Perl deve ser diferente da interface C.

Parâmetros precedidos por palavras-chave "OUTLIST" / "IN_OUTLIST" / "OUT" / "IN_OUT" são considerados
usado pela sub-rotina C via ponteiros. As palavras-chave "OUTLIST" / "OUT" indicam que o C
sub-rotina não inspeciona a memória apontada por este parâmetro, mas irá escrever através
este ponteiro para fornecer valores de retorno adicionais.

Os parâmetros precedidos pela palavra-chave "OUTLIST" não aparecem na assinatura de uso do
função Perl gerada.

Parâmetros precedidos por "IN_OUTLIST" / "IN_OUT" / "OUT" do aparecem como parâmetros para o Perl
função. Com exceção dos parâmetros "OUT", esses parâmetros são convertidos para o
tipo C correspondente, então os ponteiros para esses dados são fornecidos como argumentos para o tipo C
função. Espera-se que a função C escreva por meio desses ponteiros.

A lista de retorno da função Perl gerada consiste no valor de retorno C do
função (a menos que o XSUB seja do tipo de retorno "void" ou "A palavra-chave NO_OUTPUT" foi usada)
seguido por todos os parâmetros "OUTLIST" e "IN_OUTLIST" (na ordem de aparecimento).
No retorno do XSUB, o parâmetro Perl "IN_OUT" / "OUT" será modificado para ter o
valores escritos pela função C.

Por exemplo, um XSUB

anular
day_month (OUTLIST dia, IN unix_time, OUTLIST mês)
dia inteiro
int unix_time
mês inteiro

deve ser usado a partir do Perl como

meu ($ dia, $ mês) = dia_mês (hora);

A assinatura C da função correspondente deve ser

void day_month (int * dia, int unix_time, int * mês);

As palavras-chave "IN" / "OUTLIST" / "IN_OUTLIST" / "IN_OUT" / "OUT" podem ser combinadas com o estilo ANSI
declarações, como em

anular
day_month (OUTLIST int dia, int unix_time, OUTLIST int mês)

(aqui a palavra-chave opcional "IN" é omitida).

Os parâmetros "IN_OUT" são idênticos aos parâmetros introduzidos com "The & Unary
Operador "e colocado na seção" SAÍDA: "(consulte" A SAÍDA: Palavra-chave ").
Os parâmetros "IN_OUTLIST" são muito semelhantes, sendo a única diferença que o valor C
a função escrita por meio do ponteiro não modificaria o parâmetro Perl, mas é colocada no
lista de saída.

O parâmetro "OUTLIST" / "OUT" difere dos parâmetros "IN_OUTLIST" / "IN_OUT" apenas pelo
valor inicial do parâmetro Perl não sendo lido (e não sendo dado à função C
- que recebe algum lixo). Por exemplo, a mesma função C acima pode ser
com interface com

void day_month (OUT int dia, int unix_time, OUT int mês);

or

anular
day_month (dia, unix_time, mês)
int & dia = NO_INIT
int unix_time
int & mês = NO_INIT
SAÍDA:
dia
mês

No entanto, a função Perl gerada é chamada em um estilo muito C-ish:

meu ($ dia, $ mês);
dia_mês ($ dia, hora, $ mês);

O "comprimento (NOME)" Palavra-chave
Se um dos argumentos de entrada para a função C for o comprimento de um argumento de string "NAME",
pode-se substituir o nome do argumento de comprimento por "comprimento (NOME)" no XSUB
declaração. Este argumento deve ser omitido quando a função Perl gerada é chamada.
Por exemplo,

anular
dump_chars (char * s, short l)
{
curto n = 0;
enquanto (n <l) {
printf ("s [% d] = \" \\% # 03o \ "\ n", n, (int) s [n]);
n ++;
}
}

MÓDULO = x PACOTE = x

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

deve ser chamado como "dump_chars ($ string)".

Esta diretiva é compatível apenas com declarações de função do tipo ANSI.

Comprimento variável Parâmetro listas
XSUBs podem ter listas de parâmetros de comprimento variável, especificando reticências "(...)" no
lista de parâmetros. Este uso de reticências é semelhante ao encontrado em ANSI C. O
o programador é capaz de determinar o número de argumentos passados ​​para o XSUB examinando
a variável "itens" que o xsubpp suprimentos do compilador para todos os XSUBs. Usando este
mecanismo pode-se criar um XSUB que aceita uma lista de parâmetros de comprimento desconhecido.

O hospedeiro parâmetro para o rpcb_gettime () XSUB pode ser opcional, portanto, as reticências podem ser usadas
para indicar que o XSUB terá um número variável de parâmetros. Perl deve ser capaz
para chamar este XSUB com uma das seguintes instruções.

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

$ status = rpcb_gettime ($ timep);

O código XS, com reticências, segue.

bool_t
rpcb_gettime (timep, ...)
time_t timep = NO_INIT
PRÉ-INICIAÇÃO:
char * host = "localhost";
CÓDIGO:
if (itens> 1)
host = (char *) SvPV_nolen (ST(1));
RETVAL = rpcb_gettime (host, & timep);
SAÍDA:
cronômetro
RETIRADA

O C_ARGS: Palavra-chave
A palavra-chave C_ARGS: permite a criação de XSUBS que têm sequência de chamada diferente de
Perl em vez de C, sem a necessidade de escrever a seção CODE: ou PPCODE :. O conteúdo do
C_ARGS: o parágrafo é colocado como o argumento para a função C chamada sem qualquer alteração.

Por exemplo, suponha que uma função C seja declarada como

nth_derivative simbólico (int n, função simbólica, sinalizadores int);

e que os sinalizadores padrão são mantidos em uma variável C global "default_flags". Suponha que
você deseja criar uma interface que é chamada de

$ second_deriv = $ function->enésima derivada(2);

Para fazer isso, declare o XSUB como

simbólico
nth_derivative (função, n)
função simbólica
int substantivo
C_ARGS:
n, função, default_flags

O CÓDIGO PP: Palavra-chave
O PPCODE: palavra-chave é uma forma alternativa de CÓDIGO: palavra-chave e é usado para informar o
xsubpp compilador que o programador está fornecendo o código para controlar a pilha de argumentos
para os valores de retorno XSUBs. Ocasionalmente, pode-se querer que um XSUB retorne uma lista de
valores em vez de um único valor. Nestes casos, deve-se usar PPCODE: e então
empurre explicitamente a lista de valores na pilha. As palavras-chave PPCODE: e CODE: devem
não podem ser usados ​​juntos no mesmo XSUB.

A diferença real entre as seções PPCODE: e CODE: está na inicialização de "SP"
macro (que significa o atual Perl stack pointer), e na manipulação de dados em
a pilha ao retornar de um XSUB. Em CODE: as seções SP preservam o valor que foi
na entrada para o XSUB: SP está no ponteiro de função (que segue o último parâmetro).
Em PPCODE: as seções SP são movidas para trás, para o início da lista de parâmetros, que
permite que macros "PUSH * ()" coloquem os valores de saída no lugar que Perl espera que eles estejam quando
o XSUB retorna ao Perl.

O trailer gerado para uma seção CODE: garante que o número de valores de retorno Perl
verá é 0 ou 1 (dependendo do "vazio" do valor de retorno do C
e heurísticas mencionadas em "A variável RETVAL"). O trailer gerado para um
PPCODE: a seção é baseada no número de valores de retorno e no número de vezes "SP"
foi atualizado por macros "[X] PUSH * ()".

Observe que as macros ST (i), "XST_m * ()" e "XSRETURN * ()" funcionam igualmente bem em CODE: seções
e PPCODE: seções.

O seguinte XSUB chamará o C rpcb_gettime () função e retornará suas duas saídas
values, timep e status, para Perl como uma única lista.

anular
rpcb_gettime (host)
char * host
PRÉ-INICIAÇÃO:
tempo_t tempop;
status bool_t;
CÓDIGO PP:
status = rpcb_gettime (host, & timep);
ESTENDER (SP, 2);
PUSHs (sv_2mortal (newSViv (status)));
PUSHs (sv_2mortal (newSViv (timep)));

Observe que o programador deve fornecer o código C necessário para ter o real
rpcb_gettime () chamada e para que os valores de retorno sejam colocados corretamente no
pilha de argumentos.

O tipo de retorno "void" para esta função diz ao xsubpp compilador que o RETVAL
variável não é necessária ou usada e que não deve ser criada. Na maioria dos cenários, o
O tipo de retorno void deve ser usado com a diretiva PPCODE :.

O AMPLIAR() macro é usada para abrir espaço na pilha de argumentos para 2 valores de retorno. O
PPCODE: a diretiva faz com que o xsubpp compilador para criar um ponteiro de pilha disponível como "SP",
e é este ponteiro que está sendo usado no AMPLIAR() macro. Os valores são então
empurrado para a pilha com o PUSHs () macro.

Agora o rpcb_gettime () A função pode ser usada em Perl com a seguinte instrução.

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

Ao lidar com parâmetros de saída com uma seção PPCODE, certifique-se de lidar com a mágica de 'definir'
devidamente. Veja perlguts para detalhes sobre 'set' magic.

Voltando Indefinido E vazio listas
Ocasionalmente, o programador irá querer retornar simplesmente "undef" ou uma lista vazia se um
a função falha em vez de um valor de status separado. O rpcb_gettime () ofertas de função
apenas esta situação. Se a função for bem-sucedida, gostaríamos que ela retornasse a hora
e se falhar, gostaríamos de ter undef devolvido. No seguinte código Perl, o
o valor de $ timep será undef ou será um horário válido.

$ timep = rpcb_gettime ("localhost");

O seguinte XSUB usa o tipo de retorno "SV *" apenas como um mnemônico e usa um bloco CODE:
para indicar ao compilador que o programador forneceu todo o código necessário. O
sv_newmortal () chamada irá inicializar o valor de retorno para undef, tornando-o o padrão
valor de retorno.

SV *
rpcb_gettime (host)
caractere * hospedeiro
PRÉ-INICIAÇÃO:
tempo_t tempop;
bool_tx;
CÓDIGO:
ST(0) = sv_newmortal ();
if (rpcb_gettime (host, & timep))
sv_setnv ( ST(0), (duplo) tempop);

O próximo exemplo demonstra como alguém colocaria um undef explícito no valor de retorno,
em caso de necessidade.

SV *
rpcb_gettime (host)
caractere * hospedeiro
PRÉ-INICIAÇÃO:
tempo_t tempop;
bool_tx;
CÓDIGO:
if (rpcb_gettime (host, & timep)) {
ST(0) = sv_newmortal ();
sv_setnv ( ST(0), (duplo) tempop);
}
mais {
ST(0) = & PL_sv_undef;
}

Para retornar uma lista vazia, deve-se usar um PPCODE: bloco e não empurrar os valores de retorno
a pilha.

anular
rpcb_gettime (host)
char * host
PRÉ-INICIAÇÃO:
tempo_t tempop;
CÓDIGO PP:
if (rpcb_gettime (host, & timep))
PUSHs (sv_2mortal (newSViv (timep)));
mais {
/ * Nada colocado na pilha, então um vazio
* lista é retornada implicitamente. * /
}

Algumas pessoas podem estar inclinadas a incluir um "retorno" explícito no XSUB acima, em vez de
deixando o controle cair até o fim. Nessas situações, "XSRETURN_EMPTY" deve ser
usado, em vez disso. Isso garantirá que a pilha XSUB seja ajustada corretamente. Consultar
perlapi para outras macros "XSRETURN".

Uma vez que as macros "XSRETURN_ *" também podem ser usadas com blocos CODE, pode-se reescrever isso
exemplo como:

int
rpcb_gettime (host)
char * host
PRÉ-INICIAÇÃO:
tempo_t tempop;
CÓDIGO:
RETVAL = rpcb_gettime (host, & timep);
se (RETVAL == 0)
XSRETURN_UNDEF;
SAÍDA:
RETIRADA

Na verdade, pode-se colocar essa verificação em uma seção POSTCALL: também. Junto com PREINIT:
simplificações, isso leva a:

int
rpcb_gettime (host)
char * host
tempo_t tempop;
PÓS-CHAMADA:
se (RETVAL == 0)
XSRETURN_UNDEF;

O REQUER: Palavra-chave
A palavra-chave REQUIRE: é usada para indicar a versão mínima do xsubpp compilador necessário
para compilar o módulo XS. Um módulo XS que contém a seguinte instrução irá
compilar com apenas xsubpp versão 1.922 ou superior:

REQUERIR: 1.922

O LIMPAR: Palavra-chave
Esta palavra-chave pode ser usada quando um XSUB requer procedimentos de limpeza especiais antes de
termina. Quando a palavra-chave CLEANUP: é usada, ela deve seguir qualquer CODE: ou OUTPUT:
blocos que estão presentes no XSUB. O código especificado para o bloco de limpeza será
adicionado como as últimas instruções no XSUB.

O PÓS-CHAMADA: Palavra-chave
Esta palavra-chave pode ser usada quando um XSUB requer procedimentos especiais executados após o C
chamada de sub-rotina é executada. Quando a palavra-chave POSTCALL: é usada, ela deve preceder OUTPUT:
e CLEANUP: blocos que estão presentes no XSUB.

Veja os exemplos em "A palavra-chave NO_OUTPUT" e "Retornando listas vazias e de undef".

O bloco POSTCALL: não faz muito sentido quando a chamada da sub-rotina C é fornecida por
usuário fornecendo a seção CODE: ou PPCODE :.

O BOTA: Palavra-chave
A palavra-chave BOOT: é usada para adicionar código à função de inicialização da extensão. O
função bootstrap é gerada pelo xsubpp compilador e normalmente mantém as instruções
necessário registrar qualquer XSUBs com Perl. Com a palavra-chave BOOT: o programador pode dizer
o compilador para adicionar instruções extras à função de inicialização.

Esta palavra-chave pode ser usada a qualquer momento após a primeira palavra-chave MODULE e deve aparecer em um
linha por si só. A primeira linha em branco após a palavra-chave encerrará o bloco de código.

BOTA:
# A seguinte mensagem será impressa quando o
# a função bootstrap é executada.
printf ("Olá do bootstrap! \ n");

O VERSÃO DE VERSÃO: Palavra-chave
A VERSIONCHECK: palavra-chave corresponde a xsubpp"-versioncheck" e "-noversioncheck" de
opções. Esta palavra-chave substitui as opções da linha de comando. A verificação de versão é habilitada por
padrão. Quando a verificação de versão está habilitada, o módulo XS tentará verificar se o seu
a versão corresponde à versão do módulo PM.

Para habilitar a verificação de versão:

VERSÃO DE VERSÃO: HABILITAR

Para desativar a verificação de versão:

VERSIONCHECK: DESABILITAR

Observe que se a versão do módulo PM for um NV (um número de ponto flutuante), será
stringified com uma possível perda de precisão (atualmente cortando para nove casas decimais)
para que não corresponda mais à versão do módulo XS. Citando $ VERSION
a declaração para torná-la uma string é recomendada se números de versão longos forem usados.

O PROTÓTIPOS: Palavra-chave
A palavra-chave PROTOTYPES: corresponde a xsubppas opções "-prototypes" e "-noprototypes" de.
Esta palavra-chave substitui as opções da linha de comando. Os protótipos são ativados por padrão. Quando
protótipos são habilitados XSUBs receberão protótipos Perl. Esta palavra-chave pode ser usada
várias vezes em um módulo XS para habilitar e desabilitar protótipos para diferentes partes do
módulo.

Para habilitar protótipos:

PROTÓTIPOS: ATIVAR

Para desativar protótipos:

PROTÓTIPOS: DESATIVAR

O PROTÓTIPO: Palavra-chave
Esta palavra-chave é semelhante aos PROTÓTIPOS: palavra-chave acima, mas pode ser usada para forçar xsubpp
para usar um protótipo específico para o XSUB. Esta palavra-chave substitui todos os outros protótipos
opções e palavras-chave, mas afeta apenas o XSUB atual. Consulte "Protótipos" em perlsub
para obter informações sobre protótipos Perl.

bool_t
rpcb_gettime (timep, ...)
time_t timep = NO_INIT
PROTÓTIPO: $; $
PRÉ-INICIAÇÃO:
char * host = "localhost";
CÓDIGO:
if (itens> 1)
host = (char *) SvPV_nolen (ST(1));
RETVAL = rpcb_gettime (host, & timep);
SAÍDA:
cronômetro
RETIRADA

Se os protótipos estiverem habilitados, você pode desabilitá-los localmente para um determinado XSUB como no
seguinte exemplo:

anular
rpcb_gettime_noproto ()
PROTÓTIPO: DESATIVAR
...

O A.K.A: Palavra-chave
A palavra-chave ALIAS: permite que um XSUB tenha dois ou mais nomes Perl exclusivos e saiba quais
desses nomes foi usado quando foi invocado. Os nomes Perl podem ser totalmente qualificados com
nomes de pacotes. Cada alias recebe um índice. O compilador irá configurar uma variável chamada
"ix" que contém o índice do alias que foi usado. Quando o XSUB é chamado com
seu nome declarado "ix" será 0.

O exemplo a seguir criará os aliases "FOO :: gettime ()" e "BAR :: getit ()" para isso
função.

bool_t
rpcb_gettime (host, timep)
char * host
time_t & timep
A.K.A:
FOO :: gettime = 1
BAR :: getit = 2
INICIAR:
printf ("# ix =% d \ n", ix);
SAÍDA:
cronômetro

O SOBRECARGA: Palavra-chave
Em vez de escrever uma interface sobrecarregada usando Perl puro, você também pode usar o comando OVERLOAD
palavra-chave para definir nomes Perl adicionais para suas funções (como ALIAS: palavra-chave
acima). No entanto, as funções sobrecarregadas devem ser definidas com três parâmetros (exceto
para o nometodo () função que precisa de quatro parâmetros). Se alguma função tiver o
SOBRECARREGAR: palavra-chave, várias linhas adicionais serão definidas no arquivo c gerado por
xsubpp para se registrar com a mágica de sobrecarga.

Uma vez que os objetos abençoados são armazenados como RV's, é útil usar o mapa de tipos
recursos para pré-processar parâmetros e extrair o SV real armazenado dentro do RV abençoado.
Veja o exemplo para T_PTROBJ_SPECIAL abaixo.

Para usar a palavra-chave OVERLOAD: crie uma função XS que tenha três parâmetros de entrada (
ou use a definição '...' do estilo c) assim:

SV *
cmp (lobj, robj, troca)
Meu_Module_obj lobj
Meu_Módulo_obj robj
Troca IV
SOBRECARGA: cmp <=>
{/ * função definida aqui * /}

Nesse caso, a função sobrecarregará os dois operadores de comparação de três vias. Por
todas as operações de sobrecarga usando caracteres não alfa, você deve digitar o parâmetro sem
citando, separando várias sobrecargas com espaços em branco. Observe que "" (o stringify
sobrecarga) deve ser inserido como \ "\" (ou seja, com escape).

O CAIR PRA TRÁS: Palavra-chave
Além da palavra-chave OVERLOAD, se você precisar controlar como o Perl é gerado automaticamente em falta
operadores sobrecarregados, você pode definir a palavra-chave FALLBACK na seção de cabeçalho do módulo, como
esta:

MÓDULO = PACOTE RPC = RPC

RECUPERAÇÃO: VERDADEIRO
...

onde FALLBACK pode assumir qualquer um dos três valores TRUE, FALSE ou UNDEF. Se você não definir
qualquer valor FALLBACK ao usar OVERLOAD, o padrão é UNDEF. FALLBACK não é usado, exceto
quando uma ou mais funções usando OVERLOAD foram definidas. Por favor, veja "fallback" em
sobrecarga para mais detalhes.

O INTERFACE: Palavra-chave
Esta palavra-chave declara o XSUB atual como um guardião da assinatura de chamada fornecida. Se
algum texto segue esta palavra-chave, é considerado como uma lista de funções que têm este
assinatura e deve ser anexado ao XSUB atual.

Por exemplo, se você tiver 4 funções C multiplicar(), dividir(), adicionar(), subtrair() todos tendo
a assinatura:

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

você pode fazer com que todos usem o mesmo XSUB usando este:

simbólico
interface_s_ss (arg1, arg2)
arg1 simbólico
arg2 simbólico
INTERFACE:
multiplique a divisão
adicionar subtrair

(Este é o código XSUB completo para 4 funções Perl!) Compartilhamento de quatro funções Perl geradas
nomes com funções C correspondentes.

A vantagem desta abordagem em comparação com ALIAS: palavra-chave é que não há necessidade de
codificar uma instrução switch, cada função Perl (que compartilha o mesmo XSUB) sabe qual C
função que deve chamar. Além disso, pode-se anexar uma função extra restante() at
tempo de execução usando

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

digamos, de outro XSUB. (Este exemplo supõe que não havia INTERFACE_MACRO:
seção, caso contrário, é necessário usar outra coisa em vez de "XSINTERFACE_FUNC_SET", consulte
a próxima seção.)

O INTERFACE_MACRO: Palavra-chave
Esta palavra-chave permite definir uma INTERFACE usando uma maneira diferente de extrair uma função
ponteiro de um XSUB. O texto que segue esta palavra-chave deve fornecer o nome das macros
que extrairia / definiria um ponteiro de função. A macro extratora recebe o tipo de retorno,
"CV *" e "XSANY.any_dptr" para este "CV *". A macro setter recebe cv, e o
ponteiro de função.

O valor padrão é "XSINTERFACE_FUNC" e "XSINTERFACE_FUNC_SET". Uma palavra-chave INTERFACE
com uma lista vazia de funções podem ser omitidos se a palavra-chave INTERFACE_MACRO for usada.

Suponha que, no exemplo anterior, ponteiros de funções para multiplicar(), dividir(), adicionar(),
subtrair() são mantidos em uma matriz C global "fp []" com os deslocamentos sendo "multiply_off",
"divide_off", "add_off", "subtract_off". Então, pode-se 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)

na seção C,

simbólico
interface_s_ss (arg1, arg2)
arg1 simbólico
arg2 simbólico
INTERFACE_MACRO:
XSINTEFACE_FUNC_BYOFFSET
XSINTEFACE_FUNC_BYOFFSET_set
INTERFACE:
multiplique a divisão
adicionar subtrair

na seção XSUB.

O INCLUIR: Palavra-chave
Esta palavra-chave pode ser usada para puxar outros arquivos para o módulo XS. Os outros arquivos podem ter
Código XS. INCLUIR: também pode ser usado para executar um comando para gerar o código XS a ser puxado
no módulo.

O arquivo Rpcb1.xsh contém nossa função "rpcb_gettime ()":

bool_t
rpcb_gettime (host, timep)
char * host
time_t & timep
SAÍDA:
cronômetro

O módulo XS pode usar INCLUDE: para puxar esse arquivo para ele.

INCLUIR: Rpcb1.xsh

Se os parâmetros para a palavra-chave INCLUDE: forem seguidos por uma barra vertical ("|"), o compilador
interpretará os parâmetros como um comando. Este recurso está ligeiramente descontinuado em favor de
a diretiva "INCLUDE_COMMAND:", conforme documentado a seguir.

INCLUIR: cat Rpcb1.xsh |

Não use isto para executar perl: "INCLUDE: perl |" irá executar o perl que passa a ser o
primeiro em seu caminho e não necessariamente o mesmo perl que é usado para executar "xsubpp". Ver
"O INCLUDE_COMMAND: Palavra-chave".

O INCLUDE_COMMAND: Palavra-chave
Executa o comando fornecido e inclui sua saída no documento XS atual.
"INCLUDE_COMMAND" atribui um significado especial ao token $ ^ X por executar o mesmo perl
intérprete que está executando "xsubpp":

INCLUDE_COMMAND: gato Rpcb1.xsh

INCLUDE_COMMAND: $ ^ X -e ...

O CASO: Palavra-chave
A palavra-chave CASE: permite que um XSUB tenha várias partes distintas com cada parte atuando como
um XSUB virtual. CASE: é ganancioso e se for usado, todas as outras palavras-chave XS devem ser
contido em um CASE :. Isso significa que nada pode preceder o primeiro CASE: no XSUB e
qualquer coisa após o último CASE: está incluída nesse caso.

UM CASE: pode mudar através de um parâmetro do XSUB, através da variável "ix" ALIAS: (ver "O
ALIAS: palavra-chave "), ou talvez por meio da variável" itens "(consulte" Parâmetro de comprimento variável
Listas "). O último CASE: torna-se o omissão caso se não estiver associado a um
condicional. O exemplo a seguir mostra CASE alternado via "ix" com uma função
"rpcb_gettime ()" tendo um apelido "x_gettime ()". Quando a função é chamada como
"rpcb_gettime ()" seus parâmetros são os usuais "(char * host, time_t * timep)", mas quando o
função é chamada como "x_gettime ()" seus parâmetros são invertidos, "(time_t * timep, char
*hospedeiro)".

longo
rpcb_gettime (a, b)
CASO: ix == 1
A.K.A:
x_gettime = 1
ENTRADA:
# 'a' é timep, 'b' é host
char * b
tempo_t a = NO_INIT
CÓDIGO:
RETVAL = rpcb_gettime (b, & a);
SAÍDA:
a
RETIRADA
CASO:
# 'a' é host, 'b' é timep
char * a
time_t & b = NO_INIT
SAÍDA:
b
RETIRADA

Essa função pode ser chamada com qualquer uma das seguintes instruções. Observe o diferente
listas de argumentos.

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

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

O EXPORT_XSUB_SYMBOLS: Palavra-chave
A palavra-chave EXPORT_XSUB_SYMBOLS: é provavelmente algo de que você nunca precisará. Em perl
versões anteriores a 5.16.0, esta palavra-chave não faz nada. Começando com 5.16, símbolos XSUB
não são mais exportados por padrão. Ou seja, são funções "estáticas". Se você incluir

EXPORT_XSUB_SYMBOLS: ATIVAR

em seu código XS, os XSUBs que seguem esta linha não serão declarados "estáticos". Você pode
mais tarde desative isto com

EXPORT_XSUB_SYMBOLS: DESATIVAR

que, novamente, é o padrão que você provavelmente nunca deve alterar. Você não pode usar isso
palavra-chave em versões de perl anteriores a 5.16 para tornar XSUBs "estáticos".

O & Unário operador
O operador unário "&" na seção INPUT: é usado para informar xsubpp que deveria converter
um valor Perl para / de C usando o tipo C à esquerda de "&", mas fornece um ponteiro para este
valor quando a função C é chamada.

Isso é útil para evitar um bloco CODE: para uma função C que leva um parâmetro por
referência. Normalmente, o parâmetro não deve ser um tipo de ponteiro (um "int" ou "longo", mas
não um "int *" ou "long *").

O seguinte XSUB gerará código C incorreto. O xsubpp o compilador irá transformar isso
no código que chama "rpcb_gettime ()" com os parâmetros "(char * host, time_t timep)", mas
o verdadeiro "rpcb_gettime ()" quer que o parâmetro "timep" seja do tipo "time_t *" ao invés de
"time_t".

bool_t
rpcb_gettime (host, timep)
char * host
time_t timep
SAÍDA:
cronômetro

Esse problema é corrigido usando o operador "&". O xsubpp o compilador agora vai virar
isso em um código que chama "rpcb_gettime ()" corretamente com os parâmetros "(char * host, time_t
* timep) ". Ele faz isso carregando o" & ", de modo que a chamada de função pareça
"rpcb_gettime (host, & timep)".

bool_t
rpcb_gettime (host, timep)
char * host
time_t & timep
SAÍDA:
cronômetro

inserindo POD, Comentários e C Pré-processador instruções
As diretivas do pré-processador C são permitidas em BOOT :, PREINIT: INIT :, CODE :, PPCODE :,
POSTCALL :, e CLEANUP: blocos, bem como fora das funções. Comentários são permitidos
em qualquer lugar após a palavra-chave MODULE. O compilador irá passar as diretivas do pré-processador
por meio intocado e irá remover as linhas comentadas. A documentação POD é permitida em qualquer
ponto, nas seções de linguagem C e XS. POD deve ser encerrado com um "= corte"
comando; "xsubpp" será encerrado com um erro se não o fizer. É muito improvável que o humano
o código C gerado será confundido com POD, pois a maioria dos estilos de indentação resultam em espaços em branco
na frente de qualquer linha começando com "=". Arquivos XS gerados por máquina podem cair nessa armadilha
a menos que seja tomado cuidado para garantir que um espaço quebre a sequência "\ n =".

Os comentários podem ser adicionados aos XSUBs colocando um "#" como o primeiro espaço não em branco de uma linha.
Deve-se ter cuidado para evitar que o comentário pareça uma diretiva de pré-processador C,
para que não seja interpretado como tal. A maneira mais simples de evitar isso é colocar um espaço em branco
frente do "#".

Se você usar diretivas de pré-processador para escolher uma das duas versões de uma função, use

#if... versão1
#else / * ... version2 * /
#fim se

e não

#if... versão1
#fim se
#if... versão2
#fim se

porque caso contrário xsubpp vai acreditar que você fez uma definição duplicada do
função. Além disso, coloque uma linha em branco antes de # else / # endif para que não seja vista como parte
do corpo funcional.

utilização XS Com o C + +
Se um nome XSUB contiver "::", é considerado um método C ++. O Perl gerado
função assumirá que seu primeiro argumento é um ponteiro de objeto. O ponteiro do objeto
será armazenado em uma variável chamada THIS. O objeto deveria ter sido criado por C ++ com
da Novo() função e deve ser abençoado por Perl com o sv_setref_pv () macro. O
bênção do objeto por Perl pode ser tratada por um mapa de tipos. Um exemplo de mapa de tipos é mostrado
no final desta seção.

Se o tipo de retorno do XSUB inclui "estático", o método é considerado estático
método. Ele chamará a função C ++ usando o class :: method () sintaxe. Se o método for
não estático, a função será chamada usando o THIS->método() sintaxe.

Os próximos exemplos usarão a seguinte classe C ++.

cor da classe {
público:
cor();
~ color ();
int blue ();
void set_blue (int);

private:
int c_azul;
};

Os XSUBs para o azul() e set_blue () métodos são definidos com o nome da classe, mas o
parâmetro para o objeto (THIS ou "self") está implícito e não está listado.

int
cor azul()

anular
color :: set_blue (val)
valor int

Ambas as funções Perl esperam um objeto como o primeiro parâmetro. No C ++ gerado
codificar o objeto é denominado "THIS", e a chamada do método será realizada neste objeto.
Portanto, no código C ++, o azul() e set_blue () métodos serão chamados assim:

RETVAL = ESTE-> azul ();

ISTO-> set_blue (val);

Você também pode escrever um único método get / set usando um argumento opcional:

int
color :: blue (val = NO_INIT)
valor int
PROTÓTIPO $; $
CÓDIGO:
if (itens> 1)
ISTO-> set_blue (val);
RETVAL = ESTE-> azul ();
SAÍDA:
RETIRADA

Se o nome da função for DESTRUIR então a função C ++ "delete" será chamada e "THIS"
será fornecido como seu parâmetro. O código C ++ gerado para

anular
cor :: DESTRUIR ()

será parecido com isto:

cor * ESTE = ...; // Inicializado como no mapa de tipos

delete isso;

Se o nome da função for novo então a função "nova" do C ++ será chamada para criar um
objeto C ++ dinâmico. O XSUB irá esperar o nome da classe, que será mantido em uma variável
denominado "CLASSE", a ser fornecido como primeiro argumento.

cor *
color :: new ()

O código C ++ gerado será chamado de "novo".

RETVAL = nova cor ();

A seguir está um exemplo de um mapa de tipos que pode ser usado para este exemplo C ++.

MAPA DE TIPO
cor * O_OBJECT

SAÍDA
# O objeto Perl é abençoado em 'CLASS', que deve ser um
# char * tendo o nome do pacote para a bênção.
O_OBJETO
sv_setref_pv ($ arg, CLASS, (void *) $ var);

INPUT
O_OBJETO
if (sv_isobject ($ arg) && (SvTYPE (SvRV ($ arg)) == SVt_PVMG))
$ var = ($ tipo) SvIV ((SV *) SvRV ($ arg));
mais {
warn ("$ {Package} :: $ func_name () -".
"$ var não é uma referência SV abençoada");
XSRETURN_UNDEF;
}

Interface Estratégia
Ao projetar uma interface entre Perl e uma biblioteca C, uma tradução direta de C para
O XS (como o criado por "h2xs -x") geralmente é suficiente. No entanto, às vezes a interface
ficará muito parecido com C e, ocasionalmente, não intuitivo, especialmente quando a função C
modifica um de seus parâmetros ou retorna a falha dentro da banda (como em "valores de retorno negativos
falha média "). Nos casos em que o programador deseja criar uma interface mais parecida com Perl
a estratégia a seguir pode ajudar a identificar as partes mais críticas da interface.

Identifique as funções C com parâmetros de entrada / saída ou saída. Os XSUBs para estes
funções podem ser capazes de retornar listas para Perl.

Identifique as funções C que usam algumas informações dentro da banda como uma indicação de falha. Eles podem
ser candidatos a retornar undef ou uma lista vazia em caso de reprovação. Se a falha pode ser
detectado sem uma chamada para a função C, você pode querer usar uma seção INIT: para relatar
a falha. Para falhas detectáveis ​​após o retorno da função C, pode-se usar um
POSTCALL: seção para processar a falha. Em casos mais complicados, use CODE: ou PPCODE:
.

Se muitas funções usam a mesma indicação de falha com base no valor de retorno, você pode querer
para criar um typedef especial para lidar com essa situação. Colocar

typedef int negativo_is_failure;

próximo ao início do arquivo XS, e crie uma entrada de mapa de tipo OUTPUT para
"negative_is_failure" que converte valores negativos em "undef", ou talvez coaxar ()s. Depois de
este o valor de retorno do tipo "negative_is_failure" criará uma interface mais parecida com Perl.

Identifique quais valores são usados ​​apenas pelas próprias funções C e XSUB, digamos, quando um
parâmetro para uma função deve ser um conteúdo de uma variável global. Se o Perl não precisa
para acessar o conteúdo do valor, pode não ser necessário fornecer uma tradução
para esse valor de C para Perl.

Identifique os ponteiros nas listas de parâmetros da função C e os valores de retorno. Algumas dicas
podem ser usados ​​para implementar parâmetros de entrada / saída ou saída, eles podem ser tratados em XS com
o operador unário "&" e, possivelmente, usando a palavra-chave NO_INIT. Alguns outros vão
requerem o manuseio de tipos como "int *", e é preciso decidir qual Perl útil
tradução servirá nesse caso. Quando a semântica é clara, é aconselhável colocar
a tradução em um arquivo typemap.

Identifique as estruturas usadas pelas funções C. Em muitos casos, pode ser útil usar
o mapa de tipos T_PTROBJ para essas estruturas para que possam ser manipuladas por Perl como abençoadas
objetos. (Isso é tratado automaticamente por "h2xs -x".)

Se o mesmo tipo C é usado em vários contextos diferentes que requerem diferentes
traduções, "typedef" vários novos tipos mapeados para este tipo C e criar
mapa de tipos entradas para esses novos tipos. Use esses tipos em declarações de tipo de retorno e
parâmetros para XSUBs.

Perl objetos E C Estruturas
Ao lidar com estruturas C, deve-se selecionar T_PTROBJ or T_PTRREF para o XS
modelo. Ambos os tipos são projetados para lidar com ponteiros para objetos complexos. O tipo T_PTRREF
permitirá que o objeto Perl não seja abençoado enquanto o tipo T_PTROBJ requer que o
objeto seja abençoado. Ao usar T_PTROBJ, pode-se alcançar uma forma de verificação de tipo porque o
XSUB tentará verificar se o objeto Perl é do tipo esperado.

O seguinte código XS mostra o getnetconfigent () função que é usada com ONC + TIRPC.
O getnetconfigent () função irá retornar um ponteiro para uma estrutura C e tem o C
protótipo mostrado abaixo. O exemplo irá demonstrar como o ponteiro C se tornará um Perl
referência. Perl irá considerar esta referência como um ponteiro para um objeto abençoado e irá
tentativa de chamar um destruidor para o objeto. Um destruidor será fornecido no XS
fonte para liberar a memória usada por getnetconfigent (). Destruidores em XS podem ser criados por
especificando uma função XSUB cujo nome termina com a palavra DESTRUIR. Os destruidores XS podem ser
usado para liberar memória que pode ter sido aumentada por outro XSUB.

struct netconfig * getnetconfigent (const char * netid);

Um "typedef" será criado para "struct netconfig". O objeto Perl será abençoado em um
classe que corresponde ao nome do tipo C, com a tag "Ptr" anexada, e o nome deve
não terá espaços incorporados se for um nome de pacote Perl. O destruidor será colocado
em uma classe correspondente à classe do objeto e a palavra-chave PREFIX será usada para
corte o nome para a palavra DESTRUIR como o Perl espera.

typedef struct netconfig Netconfig;

MÓDULO = PACOTE RPC = RPC

Configuração de rede *
getnetconfigent (netid)
char * netid

MÓDULO = PACOTE RPC = NetconfigPtr PREFIX = rpcb_

anular
rpcb_DESTROY (netconf)
Netconfig * netconf
CÓDIGO:
printf ("Agora em NetconfigPtr :: DESTROY \ n");
grátis (netconf);

Este exemplo requer a seguinte entrada de mapa de tipos. Consulte perlxstypemap para mais
informações sobre como adicionar novos mapas de tipos para uma extensão.

MAPA DE TIPO
Configuração de rede * T_PTROBJ

Este exemplo será usado com as seguintes instruções Perl.

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

Quando o Perl destrói o objeto referenciado por $ netconf, ele irá enviar o objeto para o
função XSUB DESTROY fornecida. Perl não pode determinar, e não se importa, que este
objeto é uma estrutura C e não um objeto Perl. Nesse sentido, não há diferença entre
o objeto criado pelo getnetconfigent () XSUB e um objeto criado por um Perl normal
sub-rotina.

Seguramente Armazenar Estático Administração in XS
A partir do Perl 5.8, uma macro-estrutura foi definida para permitir que dados estáticos sejam
armazenados com segurança em módulos XS que serão acessados ​​a partir de um Perl multithread.

Embora projetado principalmente para uso com Perl multi-threaded, as macros foram
projetado para que funcione com Perl não encadeado também.

Portanto, é altamente recomendável que essas macros sejam usadas por todos os módulos XS que fazem
uso de dados estáticos.

A maneira mais fácil de obter um conjunto de macros de modelo para usar é especificando o "-g"
("--global") opção com h2xs (veja h2xs).

Abaixo está um módulo de exemplo que faz uso das macros.

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

/ * Dados globais * /

#define MY_CXT_KEY "BlindMice :: _ guts" XS_VERSION

typedef struct {
contagem interna;
nome do char [3] [100];
} meu_cxt_t;

START_MY_CXT

MODULE = BlindMice PACOTE = BlindMice

BOTA:
{
MEU_CXT_INIT;
MEU_CXT.contagem = 0;
strcpy (MY_CXT.name [0], "Nenhum");
strcpy (MY_CXT.name [1], "Nenhum");
strcpy (MY_CXT.name [2], "Nenhum");
}

int
newMouse (char * nome)
PRÉ-INICIAÇÃO:
dMY_CXT;
CÓDIGO:
if (MY_CXT.count> = 3) {
warning("Já tenho 3 ratos cegos");
RETVAL = 0;
}
else {
RETVAL = ++ MEU_CXT.contagem;
strcpy(MY_CXT.name[MY_CXT.count - 1], nome);
}
SAÍDA:
RETIRADA

Caracteres *
get_mouse_name(índice)
índice interno
PRÉ-INICIAÇÃO:
dMY_CXT;
CÓDIGO:
if (índice > MY_CXT.count)
croak("Existem apenas 3 ratos cegos.");
outro
RETVAL = MY_CXT.nome[índice - 1];
SAÍDA:
RETIRADA

anular
CLONE(...)
CÓDIGO:
MEU_CXT_CLONE;

MEU_CXT REFERÊNCIA

MY_CXT_KEY
Esta macro é usada para definir uma chave única para se referir aos dados estáticos para um XS
módulo. O esquema de nomenclatura sugerido, usado por h2xs, é usar uma string que
consiste no nome do módulo, na string "::_guts" e no número da versão do módulo.

#define MY_CXT_KEY "MyModule::_guts" XS_VERSION

typedef meu_cxt_t
Esta estrutura typedef devo sempre ser chamado de "my_cxt_t". As outras macros "CXT*" assumem
a existência do nome typedef "my_cxt_t".

Declare um typedef chamado "my_cxt_t" que é uma estrutura que contém todos os dados
que precisa ser intérprete-local.

typedef struct {
int algum_valor;
} meu_cxt_t;

START_MY_CXT
Sempre coloque a macro START_MY_CXT diretamente após a declaração de "my_cxt_t".

MY_CXT_INIT
A macro MY_CXT_INIT inicializa o armazenamento para a estrutura "my_cxt_t".

It devo ser chamado exatamente uma vez, normalmente em uma seção BOOT:. Se você está mantendo
múltiplos intérpretes, ele deve ser chamado uma vez em cada instância do interpretador, exceto
para intérpretes clonados dos existentes. (Mas veja "MY_CXT_CLONE" abaixo.)

dMY_CXT
Use a macro dMY_CXT (uma declaração) em todas as funções que acessam MY_CXT.

MEU_CXT
Use a macro MY_CXT para acessar membros da estrutura "my_cxt_t". Por exemplo, se
"my_cxt_t" é

typedef struct {
índice interno;
} meu_cxt_t;

então use isso para acessar o membro "index"

dMY_CXT;
MEU_CXT.índice = 2;

aMY_CXT/pMY_CXT
"dMY_CXT" pode ser bastante caro para calcular e evitar a sobrecarga de invocar
em cada função é possível passar a declaração para outras funções usando
as macros "aMY_CXT"/"pMY_CXT", por exemplo

vazio sub1() {
dMY_CXT;
MEU_CXT.índice = 1;
sub2(aMY_CXT);
}

void sub2(pMY_CXT) {
MEU_CXT.índice = 2;
}

Analogamente ao "pTHX", existem formas equivalentes para quando a macro é a primeira ou
último em vários argumentos, onde um sublinhado representa uma vírgula, ou seja, "_aMY_CXT",
"aMY_CXT_", "_pMY_CXT" e "pMY_CXT_".

MEU_CXT_CLONE
Por padrão, quando um novo interpretador é criado como uma cópia de um existente (por exemplo, via
"threads->create()"), ambos os interpretadores compartilham a mesma estrutura física my_cxt_t.
Chamar "MY_CXT_CLONE" (normalmente através da função "CLONE()" do pacote), causa um
cópia byte a byte da estrutura a ser tomada, e qualquer dMY_CXT futuro causará
a cópia a ser acessada.

MY_CXT_INIT_INTERP(meu_perl)
dMY_CXT_INTERP(meu_perl)
Essas são versões das macros que usam um interpretador explícito como argumento.

Observe que essas macros só funcionarão juntas dentro do mesmo arquivo fonte; Aquilo é um
dMY_CTX em um arquivo de origem acessará uma estrutura diferente de um dMY_CTX em outro
arquivo fonte.

Com reconhecimento de thread . interfaces de
A partir do Perl 5.8, no nível C/C++, o Perl sabe como encapsular interfaces de sistema/biblioteca
que possuem versões com reconhecimento de thread (por exemplo, getpwent_r()) em macros de frontend (por exemplo getpwent ())
que tratam corretamente a interação multithread com o interpretador Perl. Isso vai
acontecer de forma transparente, a única coisa que você precisa fazer é instanciar um interpretador Perl.

Este encapsulamento acontece sempre ao compilar a fonte do núcleo Perl (PERL_CORE é definido) ou o
Extensões de núcleo Perl (PERL_EXT está definido). Ao compilar o código XS fora do núcleo Perl
o embrulho não ocorre. Observe, no entanto, que misturar as formas _r (como Perl
compilado para operação multithread servirá) e os formulários _r-less não são bem
definidos (resultados inconsistentes, corrupção de dados ou até falhas se tornam mais prováveis), nem
é muito portátil.

EXEMPLOS


Arquivo "RPC.xs": Interface com algumas funções da biblioteca de ligação ONC+ RPC.

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

#incluir

typedef struct netconfig Netconfig;

MÓDULO = PACOTE RPC = RPC

SV *
rpcb_gettime(host="localhost")
char * host
PRÉ-INICIAÇÃO:
tempo_t tempop;
CÓDIGO:
ST(0) = sv_newmortal ();
if (rpcb_gettime (host, & timep))
sv_setnv ( ST(0), (duplo) tempo );

Configuração de rede *
getnetconfigent(netid="udp")
char * netid

MÓDULO = PACOTE RPC = NetconfigPtr PREFIX = rpcb_

anular
rpcb_DESTROY (netconf)
Netconfig * netconf
CÓDIGO:
printf("NetconfigPtr::DESTROY\n");
grátis (netconf);

Arquivo "typemap": Typemap personalizado para RPC.xs. (cf. perlxstypemap)

MAPA DE TIPO
Configuração de rede * T_PTROBJ

Arquivo "RPC.pm": módulo Perl para a extensão RPC.

pacote RPC;

exigir exportador;
requer DynaLoader;
@ISA = qw (Exportador DynaLoader);
@EXPORT = qw(rpcb_gettime getnetconfigent);

RPC de inicialização;
1;

Arquivo "rpctest.pl": Programa de teste Perl para a extensão RPC.

usar RPC;

$netconf = getnetconfigent();
$a = rpcb_gettime();
print "hora = $a\n";
print "netconf = $netconf\n";

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

RESSALVAS


O código XS tem acesso total às chamadas do sistema, incluindo as funções da biblioteca C. Tem assim o
capacidade de interferir com coisas que o núcleo Perl ou outros módulos configuraram,
como manipuladores de sinal ou manipuladores de arquivo. Pode mexer com a memória, ou qualquer número de
coisas nocivas. Não.

Alguns módulos têm um loop de eventos, aguardando a entrada do usuário. É altamente improvável que dois
esses módulos funcionariam adequadamente juntos em um único aplicativo Perl.

Em geral, o interpretador perl se vê como o centro do universo, tanto quanto o
Programa Perl vai. O código XS é visto como um companheiro de ajuda, para realizar coisas que perl
não faz, ou não faz rápido o suficiente, mas sempre subserviente ao perl. O código XS mais próximo
aderir a este modelo, os conflitos menos prováveis ​​ocorrerão.

Uma área onde houve conflito é em relação às localidades C. (Veja perllocale.)
perl, com uma exceção e salvo indicação em contrário, configura a localidade subjacente do
programa está sendo executado na localidade passada para ele do ambiente. Isto é um
diferença importante de um programa genérico de linguagem C, onde a localidade subjacente é o
Locale "C", a menos que o programa o altere. A partir da v5.20, essa localidade subjacente é
completamente oculto do código perl puro fora do escopo léxico de "usar localidade", exceto para
algumas chamadas de função no módulo POSIX que necessariamente o utilizam. Mas o
localidade subjacente, com essa exceção é exposta ao código XS, afetando todas as bibliotecas C
rotinas cujo comportamento é dependente de localidade. É melhor seu código XS não assumir que o
localidade subjacente é "C". A exceção é a categoria de localidade "LC_NUMERIC" e a
razão pela qual é uma exceção é que a experiência mostrou que pode ser problemático para o XS
código, enquanto não tivemos relatos de problemas com as outras categorias de localidade. E
a razão para esta categoria ser problemática é que o caractere usado como decimal
ponto pode variar. Muitas línguas européias usam uma vírgula, enquanto o inglês e, portanto, o Perl são
esperando um ponto (U+002E: FULL STOP). Muitos módulos podem lidar apenas com o caractere radix
sendo um ponto, e então perl tenta fazê-lo assim. Até Perl v5.20, a tentativa foi
apenas para definir "LC_NUMERIC" na inicialização para a localidade "C". Qualquer setlocale () de outra forma
mudaria; isso causou algumas falhas. Portanto, a partir da v5.22, o perl tenta
mantenha "LC_NUMERIC" sempre definido como "C" para código XS.

Para resumir, veja o que esperar e como lidar com localidades no código XS:

Código XS sem reconhecimento de localidade
Lembre-se de que, mesmo que você ache que seu código não reconhece a localidade, ele pode chamar um C
função de biblioteca que é. Espero que a página de manual para tal função indique
essa dependência, mas a documentação é imperfeita.

A localidade atual é exposta ao código XS, exceto possivelmente "LC_NUMERIC" (explicado em
o próximo parágrafo). Não houve relatos de problemas com os outros
categorias. Perl inicializa as coisas na inicialização para que a localidade atual seja aquela
que é indicado pelo ambiente do usuário em vigor naquele momento. Ver
"AMBIENTE" em perllocale.

No entanto, até a v5.20, o Perl inicializou as coisas na inicialização para que "LC_NUMERIC"
foi definido para a localidade "C". Mas se qualquer código em qualquer lugar o mudasse, ele permaneceria
mudado. Isso significa que seu módulo não pode contar com "LC_NUMERIC" sendo algo em
particular, e você não pode esperar que números de ponto flutuante (incluindo strings de versão)
têm pontos neles. Se você não permitir um não-ponto, seu código pode quebrar se alguém
em qualquer lugar mudou a localidade. Por esta razão, v5.22 mudou o comportamento para que Perl
tenta manter "LC_NUMERIC" na localidade "C", exceto em torno das operações internas
onde deveria ser outra coisa. O código XS mal comportado sempre poderá mudar
a localidade de qualquer maneira, mas a instância mais comum disso é verificada e tratada.

Código XS com reconhecimento de localidade
Se a localidade do ambiente do usuário for desejada, não deve haver necessidade de XS
código para definir a localidade exceto para "LC_NUMERIC", pois o perl já o configurou. XS
código deve evitar alterar a localidade, pois pode afetar adversamente outros, não relacionados,
código e pode não ser thread-safe. No entanto, algumas bibliotecas alienígenas que podem ser chamadas
configurá-lo, como "Gtk". Isso pode causar problemas para o núcleo perl e outros módulos.
A partir da v5.20.1, chamando a função sincronizar_locale() de XS deve ser suficiente
para evitar a maioria desses problemas. Antes disso, você precisa de uma instrução Perl pura que
faz isso:

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

Caso seu código XS precise da localidade "LC_NUMERIC" subjacente, há
macros disponíveis para acessar isso; consulte "Funções e macros relacionadas a localidade" em perlapi.

XS VERSÃO


Este documento abrange os recursos suportados por "ExtUtils::ParseXS" (também conhecido como "xsubpp")
3.13_01.

Use perlxs online usando serviços onworks.net


Servidores e estações de trabalho gratuitos

Baixar aplicativos Windows e Linux

  • 1
    Blackfriday
    Blackfriday
    Blackfriday é um processador Markdown
    implementado em Go. É paranóico sobre
    sua entrada (para que você possa alimentá-lo com segurança
    dados fornecidos pelo usuário), é rápido,
    suporta c...
    Baixar Blackfriday
  • 2
    Fonte QNAP NAS GPL
    Fonte QNAP NAS GPL
    Fonte GPL para QNAP Turbo NAS.
    Público: Desenvolvedores. Interface de usuário:
    Baseado na Web. Linguagem de programação: C,
    Java. Categorias:Sistema, Armazenamento,
    Kernel do sistema operacional...
    Baixe a fonte QNAP NAS GPL
  • 3
    limpeza profunda
    limpeza profunda
    Um script Kotlin que destrói todos os builds
    caches de projetos Gradle/Android.
    Útil quando o Gradle ou o IDE permitem que você
    abaixo. O script foi testado em
    macOS, mas...
    Baixar limpeza profunda
  • 4
    Plug-in Eclipse Checkstyle
    Plug-in Eclipse Checkstyle
    O plug-in Eclipse Checkstyle
    integra o código Java Checkstyle
    auditor no IDE Eclipse. O
    plug-in fornece feedback em tempo real para
    o usuário sobre viol ...
    Baixe o plug-in Eclipse Checkstyle
  • 5
    AstrOrzPlayer
    AstrOrzPlayer
    AstrOrz Player é um media player gratuito
    software, parte baseado em WMP e VLC. o
    jogador é de estilo minimalista, com
    mais de dez cores temáticas, podendo também
    b ...
    Baixar AstrOrzPlayer
  • 6
    Movistartv
    Movistartv
    Kodi Movistar+ TV é um ADDON para XBMC/
    Kodi que permite dispor de um
    decodificador de serviços IPTV de
    Movistar integrado em um dos
    centros de mídia ma...
    baixar movistv
  • Mais "

Comandos Linux

Ad