2010-10-29 7 views
12

Bien, esta es una pregunta muy interesante y puede que no exista una manera fácil de hacerlo, pero pensé que la descartaría antes de decidir que la modificación de Perl es mi respuesta subyacente.Llamando a la función C de Perl dentro de la aplicación de C incrustada

Así que tengo una aplicación C que llama a los scripts de Perl de forma incrustada. Todo esto funciona bien y es genial que pueda pasar información y recuperar la información. SIN EMBARGO, ahora en mi próxima conquista; Debo permitir que mis scripts incrustados puedan llamar a algunas funciones dentro de la aplicación C que lo LLAMARON ORIGINALMENTE.

Esto es importante porque XSUB requeriría que fuera una biblioteca externa; pero no quiero que sea una biblioteca externa, quiero que sea una llamada directa a la (s) función (es) C. Ahora quizás esto se puede hacer a través de XSUB y acabo de leer y entender mal.

Application -(run)-> Perl 

Application <-(function_x())- Perl 

Application -(returnfunction_x)-> Perl 

La razón de que esto no puede ser una biblioteca externa es porque yo estoy confiando en los datos que se crearon exclusivamente/almacenados dentro de la aplicación.

+0

La forma de hacerlo en Python es crear una función FFI en C y luego agregarla al diccionario de un módulo virtual que importa la secuencia de comandos de Python. No estoy seguro si se hace de la misma manera en Perl. –

Respuesta

7

XSUB en realidad no requieren que haya una biblioteca externa. Simplemente brindan la capacidad de llamar a una función c desde el espacio perl y proporcionan cierta conveniencia al mapear las convenciones de llamada entre C y Perl.

Todo lo que necesita hacer es registrar los XSUB compilados en la aplicación de integración con el intérprete de Perl que está integrando.

#include "XSUB.h" 

XS(XS_some_func); 
XS(XS_some_func) 
{ 
    dXSARGS; 
    char *str_from_perl, *str_from_c; 

    /* get SV*s from the stack usign ST(x) and friends, do stuff to them */ 
    str_from_perl = SvPV_nolen(ST(0)); 

    /* do your c thing calling back to your application, or whatever */ 
    str_from_c = some_c_func(str_from_perl); 

    /* pack up the c retval into an sv again and return it on the stack */ 
    mXPUSHp(c_str); 
    XSRETURN(1); 
} 

/* register the above XSUB with the perl interpreter after creating it */ 
newXS("Some::Perl::function", XS_some_func, __FILE__); 

Cuando la incrustación de Perl, este tipo de cosas se hace generalmente en la función xs_init se pasa a parse_perl.

EXTERN_C void boot_DynaLoader (pTHX_ CV* cv); 

static void 
xs_init (pTHX) 
{ 
    newXS("Some::Perl::function", XS_some_func, __FILE__); 
    /* possibly also boot DynaLoader and friends. perlembed has more 
    * details on this, and ExtUtils::Embed helps as well. */ 
    newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); 
} 

perl_parse(my_perl, xs_init, argc, my_argv, NULL); 

Después de que usted será capaz de llamar a la XSUB como Some::Perl::function desde el espacio Perl, y que a su vez XSUB es libre para volver a llamar a la aplicación de la forma que quiera.

+0

Entonces, ¿la primera sección que pegó va a un archivo .xs? – Suroot

+0

Es un código C, así que me gustaría ponerlo en un archivo '.c', pero dudo que el compilador de C adecuado se preocupe por la extensión de los archivos que le pidas compilar :-) – rafl

+1

Todo tiene sentido ahora; Estaba pensando que las nuevas cosas de XS realmente solo hablaban de cargar módulos. No se pudo encontrar mucha documentación sobre perl-xs; más apreciado señor! – Suroot

Cuestiones relacionadas