Interfaces de Scripting para librerias en C

981 views

Published on

Entendiendo como extender lenguajes de scripting como PHP con extensiones en C

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
981
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Interfaces de Scripting para librerias en C

  1. 1. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: Interfaces de scripting para librerías en C Moisés H. Silva CIISA 2008 1
  2. 2. :: Interfaces de scripting para librerías en C :: 1. Lenguajes de scripting :: CIISA 2008 :: Agenda para C en PHP 2. Interfaces * Funcionamiento. * ¿Por qué? * Ventajas y desventajas. * Extensiones. * PHP, PERL, Python. * Zend Engine. 3. Construcción de una Extensión PHP * Estructuras de registro. * Variables. * Funciones. * Clases. * Compilación. 2
  3. 3. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: Agenda 4. SWIG (Simplified Wrapper and Interface Generator) * Funcionamiento general 3
  4. 4. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Lenguajes de scripting] Funcionamiento :: Los lenguajes de scripting son comunmente conocidos como interpretados. :: El intérprete es un programa que se encarga de parsear y ejecutar las instrucciones indicadas en el script (código del programa). :: A diferencia de los lenguajes compilados, el lenguaje de scripting siempre depende de su interprete para poder ser ejecutado. :: Comunmente son menos estrictos con los tipos de datos y las operaciones que se pueden realizar entre los distintos tipos de variables. Son dinámicos. 4
  5. 5. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Lenguajes de scripting] Funcionamiento 5
  6. 6. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Lenguajes de scripting] Ventajas :: Manejo de memoria automático. :: Tiempo de desarrollo mucho menor comparado con lenguajes compilados. :: La curva de aprendizaje es menos pronunciada. :: Amplio espectro de bibliotecas/librerías usualmente disponibles con el interprete. :: Alto nivel de portabilidad. 6
  7. 7. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Lenguajes de scripting] Desventajas :: Baja eficiencia. (Tiempo de ejecución prolongado) :: Usualmente limitados al universo de funcionalidad proveido por el intérprete y sus extensiones. :: Bugs que usualmente pueden ser encontrados en tiempo de compilación ahora pueden esconderse hasta su ejecución. :: Código fuente usualmente expuesto (no necesariamente una desventaja). 7
  8. 8. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Lenguajes de scripting] PHP, PERL y Python :: Son 3 de los lenguajes de scripting más usados, particularmente en Linux. :: Sus intérpretes son de fuente abierta (open source). :: Todos han sido usados para aplicaciones web con éxito. :: Soportan orientación a objetos. :: Se encuentran soportados por el generador de interfaces SWIG. 8
  9. 9. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Lenguajes de scripting] PHP :: Creado por Rasmus Lerdof a mediados de los 90. :: Inicio como una serie de CGIs en C para generar páginas web de forma dinámica. :: PHP evolucionó de forma desorganizada por mucho tiempo. :: La compañia Zend le ha dado forma al lenguaje para ser más robusto. :: Soporta código estructurado y orientado a objetos. :: Su sintaxis es muy similar a C++ con algunas ideas tomadas de Java. :: Aunque su fuerte es la creación de sitios web, puede ser usado como de propósito general. 9
  10. 10. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Lenguajes de scripting] PERL :: Creado por Larry Wall a finales de los 80. :: Lenguaje de scripting de propósito general. :: Muy popular sobre todo en Linux para la automatización de tareas en servidores. :: Al igual que PHP ha ido evolucionando y agregando nuevas características como la orientación a objetos. :: Siempre expone muchas formas de hacer la misma tarea. :: La sintaxis puede llegar a ser muy extraña. 10
  11. 11. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Lenguajes de scripting] Python :: Escrito por Guido van Rossum a principios de los 90. :: Su modelo de programación es principalmente orientado a objetos. :: Programación estructurada y funcional también soportadas en menor medida. :: Curiosamente usa los “tabs” para definir bloques de código. 11
  12. 12. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Interfaces en C para PHP] ¿Por qué? :: Soportar funcionalidad solo disponible en librerías en C/C++ :: Exponer interfaces mas simples y/u orientadas a objetos a los usuarios. :: Mejorar el performance de tus scripts. :: Distribuir módulos de funcionalidad sin código fuente. 12
  13. 13. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Interfaces en C para PHP] Extensiones :: Las extensiones de PHP son shared object's o DLL's que exponen funcionalidad no disponible en el core de PHP. :: Al iniciar, el core de PHP carga las extensiones requeridas por el script de entrada. :: Las extensiones proveen de su funcionalidad a través de funciones, clases, constantes etc. :: Cada extensión es responsable de sus recursos. El usuario de la extensión no tiene porque preocuparse de la liberación de recursos. 13
  14. 14. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Interfaces en C para PHP] Extensiones 14
  15. 15. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Interfaces en C para PHP] Zend Engine :: El Zend Engine es lo que se conoce como el core de PHP. :: Se encarga del manejo de memoria y toda la funcionalidad básica de un intérprete. :: Las extensiones pueden ser cargadas por el ZE ó compiladas de forma interna. :: El ZE lleva a cabo el manejo de los ciclos de vida de las extensiones y los scripts. 15
  16. 16. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Interfaces en C para PHP] Zend Engine :: El ciclo de vida de una extensión de PHP se compone de 5 etapas: -> Inicialización: El proceso donde habita el core es iniciado. -> Activación: Cada vez que la extensión es usada por un nuevo script. -> Ejecución: El script hace uso de la funcionalidad de la extensión. -> Desactivación: El script finalizó. -> Finalización: El proceso donde habita el core está siendo terminado. 16
  17. 17. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Interfaces en C para PHP] Zend Engine :: El ZE expone APIs a sus extensiones para: -> Manejo de memoria. -> Creación y manipulación de variables. -> Reference counting. -> Consulta de las configuraciones del INI. -> Registro de clases y funciones. -> Obtención y retorno de variables de “user space” 17
  18. 18. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Interfaces en C para PHP] Zend Engine :: Dentro de ambiente del ZE, existen 2 tipos de memoria: -> Memoria persistente o no manejada. -> Memoria de request o manejada. :: La memoria persistente es aquella no manejada por el ZE, como aquella memoria solicitada via malloc y por funciones ajenas al ZE. :: La memoria de request o manejada es aquella solicitada por APIs del ZE como emalloc(), ecalloc(), erealloc(), estrdup() etc. :: La memoria de request o manejada solo persiste durante un hit de una página web. 18
  19. 19. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Interfaces en C para PHP] Zend Engine :: El I/O de datos también es controlado por el ZE. :: El ZE expone algunas API para la salida de datos: -> PHP_API int printf(const char *format, ...) -> PHP_API int php_body_write(const char *str, uint str_length TSRMLS_DC) -> ZEND_API int zend_print_variable(zval *var) :: El uso directo de stdout debe ser evitado, sobretodo cuando php está corriendo en un ambiente web debido a que la salida en realidad la salida usualmente es dirigida por el ZE a la interfaz del servidor web. 19
  20. 20. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Construcción de una extensión PHP] Estructuras de registro :: El ZE carga las extensiones usando información obtenida de una estructura llamada zend_module_entry. :: zend_module_entry define datos generales de la extensión: -> Nombre de la extensión. -> Lista de funciones y sus manejadores. -> Apuntadores a funciones de inicialización y destrucción. -> Versión del módulo. -> Otras propiedades generales ... 20
  21. 21. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Construcción de una extensión PHP] Estructuras de registro 21
  22. 22. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Construcción de una extensión PHP] Estructuras de registro :: Las funciones de inicialización (MINIT) y destrucción (MSHUTDOWN) de módulo son llamadas una sola vez en la vida de la extensión. :: Durante MINIT se deben registrar las clases, constantes y demás funcionalidad que será expuesta al usuario. :: Durante MSHUTDOWN deben liberarse los recursos que pudieran haber sido solicitados en MINIT. :: La declaración de MINIT y MSHUTDOWN se hace a través de macros: PHP_MINIT_FUNCTION(helloext){} PHP_MSHUTDOWN_FUNCTION(helloext){} :: Los macros generan el prototipo apropiado, como: int zm_startup_helloext(int type, int module_number TSRMLS_DC) 22
  23. 23. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Construcción de una extensión PHP] Estructuras de registro :: Las funciones de inicialización (RINIT) y destrucción (RSHUTDOWN) de request son llamadas una vez por request. :: Durante RINIT se deben solicitar los recursos que no permanecen durante requests. :: Durante RSHUTDOWN deben liberarse los recursos que fueron solicitados durante la ejecución del script, como conexiones a BD no persistentes. :: La declaración de RINIT y RSHUTDOWN se hace a través de macros: PHP_RINIT_FUNCTION(helloext){} PHP_RSHUTDOWN_FUNCTION(helloext){} :: Los macros generan el prototipo apropiado, como: int zm_activate_helloext(int type, int module_number TSRMLS_DC) 23
  24. 24. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Construcción de una extensión PHP] Variables :: Para los usuarios de PHP una variable puede cambiar de tipo de forma dinámica sin problema alguno. $variable = array('uno', 'dos'); print $variable[0]; $variable = 10; print $variable; :: PHP soporta los tipos Integer, Float, String, Boolean, Array, Object, Resource y NULL :: Internamente una variable es representada por la estructura zval. :: zval contiene la información necesaria para determinar el tipo de la variable, su valor, si es una referencia y cuantas referencias hay hacia la variable (reference counting). 24
  25. 25. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Construcción de una extensión PHP] Variables 25
  26. 26. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Construcción de una extensión PHP] Variables :: Internamente, un statement como $var = “valor”; resulta en un zval con: .type = 6; /* macro IS_STRING */ .value.str = { val = “valor”; len = 5; } .is_ref = 0; .refcount = 1; :: Al reasignar $var = array(“valor”);, el mismo zval se usa y se modifica su tipo: .type = 4; /* macro IS_ARRAY */ .value.ht = <direccion de memoria de un hash table> :: Las propiedades del zval cambian conforme al flujo del script. :: Todas las extensiones recibirán zvals representando variables del usuario. 26
  27. 27. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Construcción de una extensión PHP] Funciones :: Las funciones de PHP internamente son prefijadas con zif_ y reciben parámetros estandar. :: El macro PHP_FUNCTION ayuda en la definición del prototipo. :: La definición resultante es: void zif_nombrefuncion(int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC, void ***tsrm_ls); 27
  28. 28. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Construcción de una extensión PHP] Funciones :: El macro PHP_FUNCTION recibe como argumento el nombre de la función que deseamos exportar. PHP_FUNCTION(suma) :: El cuerpo de la función usualmente consta de: -> Recepción y parseo de argumentos con zend_parse_parameters() -> Proceso específico de la función. -> Retorno de un valor mediante los macros RETURN_XXX() 28
  29. 29. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Construcción de una extensión PHP] Funciones :: zend_parse_parameters es necesario para tomar los argumentos del stack del ZE. :: zend_parse_parameters recibe el número de argumentos a parsear, sus tipos (mediante una cadena de formato) y los apuntadores a la memoria a utilizar para guardarlos. int op1, op2; zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, “ll”, &op1, &op2); :: El valor de retorno FAILURE significa que el parseo falló y usualmente debe ser causal para mandar un error con zend_throw_exception o WRONG_PARAM_COUNT 29
  30. 30. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Construcción de una extensión PHP] Funciones :: La cadena de formato puede contener los valores: s -> el valor esperado es un string. Debemos proveer char ** e int* b -> booleano. Proveer zend_bool* l -> long. Proveer long* r, a, o, z -> resource, array, object, opaco. Proveer zval* 30
  31. 31. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Construcción de una extensión PHP] Funciones :: Para regresar un valor de la función debe usarse: RETURN_RESOURCE, RETURN_LONG, RETURN_BOOL etc. :: RETURN_STRING es especial, debe indicarse si el buffer del string debe ser duplicado o no por el ZE. El segundo parámetro del macro lo indica. RETURN_STRING(“Buffer Permanente”, 1); RETURN_STRING(variable_local, 0); 31
  32. 32. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Construcción de una extensión PHP] Funciones PHP_FUNCTION(suma) { long op1; op2; if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &op1, &op2)) { return; } RETURN_LONG((op1 + op2)); } 32
  33. 33. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Construcción de una extensión PHP] Funciones :: TSRMLS == Thread Safe Resource Manager Local Storage :: Necesario para crear scope “global” por thread. :: Existen muchos macros variantes para facilitar pasar este storage de un lado a otro. 33
  34. 34. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Construcción de una extensión PHP] Clases :: El ZE está escrito en C por lo que internamente las clases de PHP están definidas como estructuras y apuntadores a funciones. :: Una declaración en user space de una clase tiene la forma: class ClaseEnPhp {} :: Internamente tal clase tendría que registrarse usando una estructura zend_class_entry y la función zend_register_internal_class. :: El equivalente a una declaración de clase en user space es: zend_class_entry ce; INIT_CLASS_ENTRY(ce, “ClaseEnPhp”, NULL); zend_register_internal_class(&ce TSRML_CC); :: El registro de clases desde una extensión debe ser hecho en MINIT 34
  35. 35. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Construcción de una extensión PHP] Clases :: La implementación de un método de una varía poco de la de una función común. :: El macro PHP_METHOD es usado en lugar de PHP_FUNCTION. PHP_METHOD(PrimerMetodo) { // cuerpo del método } :: Características adicionales para el método como visibilidad y definición de argumentos son especificadas a través de la estructura zend_function_entry y el macro PHP_ME zend_function_entry ClaseEnPhp_methods[] = { PHP_ME(ClaseEnPhp, PrimerMetodo, NULL, ZEND_ACC_PUBLIC); }; 35
  36. 36. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Construcción de una extensión PHP] Clases :: La implementación de un método de una varía poco de la de una función común. :: El macro PHP_METHOD es usado en lugar de PHP_FUNCTION. PHP_METHOD(PrimerMetodo) { // cuerpo del método } :: Características adicionales para el método como visibilidad y definición de argumentos son especificadas a través de la estructura zend_function_entry y el macro PHP_ME zend_function_entry ClaseEnPhp_methods[] = { PHP_ME(ClaseEnPhp, PrimerMetodo, NULL, ZEND_ACC_PUBLIC); }; 36
  37. 37. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [Construcción de una extensión PHP] Compilación :: La compilación en Linux se lleva a cabo mediante un comando incluido con la distribución de PHP: “phpize” :: Antes de correr phpize se necesita crear config.m4, un script que determinará opciones de tiempo de compilación como la ubicación de librerías externas. :: Una vez creado config.m4 se procede a ejecutar phpize # phpize :: Finalmente igual que cualquier otro paquete basado en GNU autotools se instala mediante: # ./configure # make && make install 37
  38. 38. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [SWIG] Funcionamiento General :: SWIG es un generador del pegamento necesario para juntar código en C/C++ con lenguajes de más alto nivel como PHP, PERL, Python, Java etc. :: SWIG recibe como entrada un archivo especial que define las interfaces en C/C++ para generar código fuente que puede ser compilado para crear módulos del lenguaje deseado. :: Una archivo de interfaz puede ser facilmente escrito incluyendo el header donde declaras tus funciones C/C++: %module milibreria %{ #include “milibreria.h” %} 38
  39. 39. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: [SWIG] Funcionamiento General :: El archivo de interfaz se usa como entrada para SWIG. # swig -perl milibreria.i :: SWIG genera un archivo milibreria_wrap.c que funcionará como interfaz hacia PERL. :: Se compila la interfaz. # gcc -c milibreria.c milibreria_wrap.c `perl -MextUtils::Embed -e ccopts` :: Se enlaza la libreria con el wrapper de perl. # ld -G milibreria.o milibreria_wrap.o -o milibreriaperl.so 39
  40. 40. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: Referencias. http://www.hardened-php.net/ http://devzone.zend.com/ http://www.php.net/ http://www.swig.org/ http://www.php.net/internals2.ze1.zendapi 40
  41. 41. :: Interfaces de scripting para librerías en C :: :: CIISA 2008 :: Gracias. Moisés Humberto Silva Salmerón http://www.moythreads.com// moises.silva@gmail.com moyhu@mx1.ibm.commoyhu@mx1.ibm.com 41

×