From bachue at bachue.com Tue Nov 23 17:53:44 1999 From: bachue at bachue.com (Alejandro Forero Cuervo) Date: Wed Aug 4 23:58:11 2004 Subject: Crear SVs a partir de punteros en C. Message-ID: <19991123185344.A269@azul.dhis.org> Saludos. Tengo una librer?a de C que me ofrece la posibilidad de registrar funciones de callback C. La idea es que el caller pase un apuntador a su funci?n y un apuntador a un objeto que ser? pasado a la funci?n como argumento. El prototipo de la funci?n para registrar la rutina de callback es el siguiente (realmente es muy diferente, pero no importa): int register(int (*funcion)(HBInfo *), void *object); Eso har? que cuando llame ciertas funciones de la librer?a, esta llame mis funciones de callback varias veces seg?n lo que suceda. Ahora bien, en mi archivo XS, donde creo la extensi?n que permita utilizar la librer?a desde Perl, declaro la funci?n register, de tal manera que uno pueda hacer lo siguiente en Perl (realmente es muy diferente, pero no importa): use alejo; alejo::register(\&function); sub function { print "I was called!\n"; } Notar?n que por ahora no se puede pasar un objeto de uno en Perl (mientras que en C hay un apuntador object donde uno pasa un dato que le ser? pasado a la rutina de callback). Eso no es grave y ser? arreglado en el futuro. Ignoremos el detalle, no es relevante. En la funci?n asociada a register de Perl, lo que hago es, b?sicamente, lo siguiente (realmente es muy diferente, pero no importa): int nombre_de_funcion (perl_func) SV *perl_func; ALIAS: alejo::register = 1 CODE: RETVAL = register(funcion_magica, perl_func); OUTPUT: RETVAL Con eso lo que logro es que cuando la librer?a de C necesite llamar el callback, llame funcion_magica y le pase el SV de la rutina (el parametro perl_func), para que funcion_magica se encarge de llamarla. Ahora bien, como se puede ver en el prototipo de la funci?n register de C, funcion_magica tiene el siguiente prototipo y est? declarada al comienzo de mi archivo XS: int funcion_magica (Info *data); El tipo Info contiene, principalmente (desde el punto de vista del usuario de la librer?a), una tabla de s?mbolos con punteros a diferentes funciones que se pueden llamar dentro de funcion_magica (de la forma data->sym->funcion(...)). En la declaraci?n de funcion_magica tengo que extraer de data el SV de la rutina de Perl (que antes llam? perl_func, al registrar funcion_magica como callback) para llamarlo. Tengo que llamarlo. Y he aqu? el problema. Al llamarlo, quiero pasarle a la rutina de Perl como parametro ese mismo apuntador data, para que desde la rutina se pueda jugar con esa informaci?n. Para esto, tengo que crear un SV con el valor de data y decirle a Perl a que clase asociarlo. Por ejemplo, en mi archivo XS declaro la clase Info y creo varios m?todos asociados a ella. Yo quiero que en el c?digo de Perl de la rutina de callback, las personas puedan hacer: my $var = shift; $var->addcontent("foo"); $var->setvalue("bar"); En mi archivo XS declaro la clase Info y sus m?todos, tales como addcontent y setvalue (realmente son m?todos muy diferentes, pero no importa). El problema es que en funcion_magica no tengo el SV para meter en el stack de Perl. Es decir, necesito una funci?n que probablemente tenga el siguiente prototipo: SV *sv_new_blah ( char *classname, void *value ); Esa funci?n crear? un SV de tipo classname cuyo valor ser? value, de tal modo que cuando en la rutina de Perl lo saquen de la pila, puedan hacerle las cosas que en mi XS defino que se pueden hacer en esa clase. He estado mirando los manuales y lo m?s relevante que encontr? fue la funci?n newSVrv: SV* newSVrv(SV* rv, char* classname); El manual (perlguts) dice: /* Still under construction */ Upgrades rv to reference if not already one. Creates new SV for rv to point to. If classname is non-null, the SV is blessed into the specified class. SV is returned. Sin embargo, me imagino que no puedo pasar cualquier apuntador como rv simplemente haciendole un cast. Dice `SV is returned'. Obviamente un SV es retornado, de acuerdo con el prototipo. Es el mismo rv el que es retornado? En fin, alguien con m?s experiencia (la primera vez que program? en Perl fue hace menos de dos semanas) sabe como hacerlo? Gracias. Alejo. http://bachue.com/alejo Pd: La librer?a se llama HB y es un sistema bastante nuevo para construir contenido en web de manera din?mica, extensible a trav?s de m?dulos cargados en tiempo de ejecuci?n, jugando el mismo papel que Perl+CGI / PHP / MetaHTML / ASP y similares. Pueden encontrar m?s informaci?n al respecto en . -- The mere formulation of a problem is far more essential than its solution. -- Albert Einstein. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 232 bytes Desc: not available Url : http://mail.pm.org/archives/bogota-pm/attachments/19991123/522ff1cd/attachment.bin