Conversion extension C -> php

Petit nouveau ! | 9 Messages

09 sept. 2010, 17:54

Bonjour,
je suis en train de developper un generateur d'extension php en python à partir d'un fichier gabarit XML.
j'aimerais simplement savoir si je suis sur la bonne voie, la question ne porte pas sur le generateur python bien sur mais sur le fichier php que je genere :
il y en a 4 que je genere :
- config.m4
- config.w32
- module.c
- php_module.c

ma question porte d'abord sur le fichier php_module.c, je voudrais savoir si il est correctement généré (honnetement j'ai du mal a comprendre les fonctions de l'API ZEND) je me suis basé sur different tutos et jai aussi regardé les differentes extensions deja intégré à PHP, voici mon code généré :

Code : Tout sélectionner

#ifndef FREEAGE_MODULE_MODULE_INCLUDED #define FREEAGE_MODULE_MODULE_INCLUDED #define PHP_MODULE_EXTNAME "module" #define PHP_MODULE_EXTVER "1.0" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "net_types.h" #include <stdarg.h> /* Registration module inputs. */ extern zend_module_entry module_module_entry; #define phpext_module_ptr &module_module_entry PHP_MINIT_FUNCTION(module); PHP_MINFO_FUNCTION(module); /* Declaration of functions to create. */ PHP_FUNCTION(test_module); PHP_FUNCTION(test_module_result); PHP_FUNCTION(test_sql); PHP_FUNCTION(test_sql_result); #ifdef __cplusplus extern "C" { #endif ZEND_BEGIN_MODULE_GLOBALS(module) struct net_struct; struct net_packet; struct net_func_instance; struct net_func_callbacks; struct net_client; /* test_module params declaration. */ struct test_module_params { net_int_t arg; /*< An argument. */ }; /* test_module result declaration. */ struct test_module_result { net_int_t ret; /*< A result. */ }; /* A test function. */ /* * \param client A pointer to the client structure. * \param callbacks An optional pointer to the instance callbacks. * \param arg An argument. * \return A pointer to a function instance, or NULL if an error occured. */ struct net_func_instance * test_module ( struct net_client * client, const struct net_func_callbacks * callbacks, const net_int_t arg ); /* Pop a result from an instance of the function test_module. */ /* * \see test_module * \param instance A pointer to an instance of the function test_module. * \return A pointer to a result or NULL if no results are available. */ const struct test_module_result * test_module_result ( struct net_func_instance * instance ); /* test_sql params declaration. */ struct test_sql_params { net_char_t name [32]; /*< The test argument. */ }; /* test_sql result declaration. */ struct test_sql_result { net_int_t intval; /*< An integer. */ net_float_t floatval; /*< A float. */ net_char_t strval [32]; /*< A string. */ }; /* A function to test the sql client. */ /* * \param client A pointer to the client structure. * \param callbacks An optional pointer to the instance callbacks. * \param name The test argument. * \return A pointer to a function instance, or NULL if an error occured. */ struct net_func_instance * test_sql ( struct net_client * client, const struct net_func_callbacks * callbacks, const net_char_t name [32] ); /* Pop a result from an instance of the function test_sql. */ /* * \see test_sql * \param instance A pointer to an instance of the function test_sql. * \return A pointer to a result or NULL if no results are available. */ const struct test_sql_result * test_sql_result ( struct net_func_instance * instance ); ZEND_END_MODULE_GLOBALS(module) #ifdef ZTS #define MODULE_G(v) TSRMG(module_globals_id, zend_module_globals*, v) #else #define MODULE_G(v) (module_globals.v) #endif ZEND_EXTERN_MODULE_GLOBALS(module) #ifdef __cplusplus } #endif #endif /* FREEAGE_MODULE_MODULE_INCLUDED */
et voici mon fichier header d'origine :

Code : Tout sélectionner

#ifndef FREEAGE_MODULE_MODULE_INCLUDED #define FREEAGE_MODULE_MODULE_INCLUDED #include "net_types.h" #include <stdarg.h> #ifdef __cplusplus extern "C" { #endif struct net_struct; struct net_packet; struct net_func_instance; struct net_func_callbacks; struct net_client; /// test_module params declaration. struct test_module_params { net_int_t arg; ///< An argument. }; /// test_module result declaration. struct test_module_result { net_int_t ret; ///< A result. }; /// A test function. /** * \param client A pointer to the client structure. * \param callbacks An optional pointer to the instance callbacks. * \param arg An argument. * \return A pointer to a function instance, or NULL if an error occured. */ struct net_func_instance * test_module ( struct net_client * client, const struct net_func_callbacks * callbacks, const net_int_t arg ); /// Pop a result from an instance of the function test_module. /** * \see test_module * \param instance A pointer to an instance of the function test_module. * \return A pointer to a result or NULL if no results are available. */ const struct test_module_result * test_module_result ( struct net_func_instance * instance ); /// test_sql params declaration. struct test_sql_params { net_char_t name [32]; ///< The test argument. }; /// test_sql result declaration. struct test_sql_result { net_int_t intval; ///< An integer. net_float_t floatval; ///< A float. net_char_t strval [32]; ///< A string. }; /// A function to test the sql client. /** * \param client A pointer to the client structure. * \param callbacks An optional pointer to the instance callbacks. * \param name The test argument. * \return A pointer to a function instance, or NULL if an error occured. */ struct net_func_instance * test_sql ( struct net_client * client, const struct net_func_callbacks * callbacks, const net_char_t name [32] ); /// Pop a result from an instance of the function test_sql. /** * \see test_sql * \param instance A pointer to an instance of the function test_sql. * \return A pointer to a result or NULL if no results are available. */ const struct test_sql_result * test_sql_result ( struct net_func_instance * instance ); #ifdef __cplusplus } #endif #endif /* FREEAGE_MODULE_MODULE_INCLUDED */
Merci d'avance !

Petit nouveau ! | 9 Messages

10 sept. 2010, 17:59

je vais simplifier ma question.
Comment transformer cette fonction pour l'integrer dans une extension php ?

Code : Tout sélectionner

struct net_func_instance * test_module ( struct net_client * client, const struct net_func_callbacks * callbacks, const net_int_t arg ) { return net_client_call_function(client, &test_module_func_def, callbacks, arg); }
comme ceci ?

Code : Tout sélectionner

ZEND_BEGIN_ARG_INFO_EX(arginfo_test_module) // Que mettre ici ? // et ici ? ZEND_END_ARG_INFO() const zend_function_entry module_functions[] = { PHP_FE(test_module, arginfo_test_module) // ca c'est bon j'imagine {NULL, NULL, NULL} }; PHP_FUNCTION(test_module) { return net_client_call_function(client, &test_module_func_def, callbacks, arg); }

Petit nouveau ! | 9 Messages

17 sept. 2010, 11:32

j'ai avancé sur mon extension mais je ne suis pas sur des mes types de données ni comment les retourner !
faut il les retourner avec ZEND_REGISTER_RESOURCE(return_value, ptr_test_sql, le_test_sql); ?

doit t'on definir des arg info ?

je vous redonnes mon code modifié :

php_module.h :

Code : Tout sélectionner

#ifndef FREEAGE_MODULE_MODULE_INCLUDED #define FREEAGE_MODULE_MODULE_INCLUDED #ifdef __cplusplus extern "C" { #endif #define PHP_MODULE_EXTNAME "module" #define PHP_MODULE_EXTVER "1.0" #ifdef ZTS #include "TSRM.h" #endif #include "net_types.h" #include <stdarg.h> /* Registration module inputs. */ extern zend_module_entry module_module_entry; #define phpext_module_ptr &module_module_entry /* Declaration of functions to create. */ PHP_MINIT_FUNCTION(module); PHP_MINFO_FUNCTION(module); PHP_MSHUTDOWN_FUNCTION(module); PHP_FUNCTION(test_module); PHP_FUNCTION(test_module_result); PHP_FUNCTION(test_sql); PHP_FUNCTION(test_sql_result); ZEND_BEGIN_MODULE_GLOBALS(module) /* test_module result declaration. */ typedef struct { net_int_t ret; /*< A result. */ } test_module_result; /* test_sql result declaration. */ typedef struct { net_int_t intval; /*< An integer. */ net_float_t floatval; /*< A float. */ net_char_t strval [32]; /*< A string. */ } test_sql_result; ZEND_END_MODULE_GLOBALS(module) #ifdef ZTS #define MODULE_G(v) TSRMG(module_globals_id, zend_module_globals *, v) #else #define MODULE_G(v) (module_globals.v) #endif ZEND_EXTERN_MODULE_GLOBALS(module) #ifdef __cplusplus } #endif #endif /* FREEAGE_MODULE_MODULE_INCLUDED */
module.c :

Code : Tout sélectionner

#if HAVE_MODULE #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_ini.h" #include "php_module.h" #include "net_endian.h" #include "net_struct.h" #include "net_func.h" #include "net_client.h" #include <stddef.h> #include <string.h> /* Arginfo */ ZEND_BEGIN_ARG_INFO_EX(arginfo_test_module) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_test_module_result) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_test_sql) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_test_sql_result) ZEND_END_ARG_INFO() /* Initialise global variables */ ZEN_DECLARE_MODULE_GLOBALS(module) static void php_module_init_globals (zend_module_globals * module_globals) { module_globals->test_module_result->ret = 0; module_globals->test_sql_result->intval = 0; module_globals->test_sql_result->floatval = 0; module_globals->test_sql_result->strval = NULL; } /* Every user visible function must have an entry in this function. */ const zend_function_entry module_functions [] = { PHP_FE(test_module, arginfo_test_module) PHP_FE(test_module_result, arginfo_test_module_result) PHP_FE(test_sql, arginfo_test_sql) PHP_FE(test_sql_result, arginfo_test_sql_result) {NULL, NULL, NULL} }; /* Information module. */ zend_module_entry module_module_entry = { #if ZEND_MODULE_API_NO >= 20010901 STANDARD_MODULE_HEADER, #endif PHP_MODULE_EXTNAME, module_functions, /* Functions */ PHP_MINIT(module), /* MINIT */ PHP_MSHUTDOWN(module), /* MSHUTDOWN */ NULL, /* RINIT */ NULL, /* RSHUTDOWN */ PHP_MINFO(module), /* MINFO */ #if ZEND_MODULE_API_NO >= 20010901 PHP_MODULE_EXTVER, #endif STANDARD_MODULE_PROPERTIES }; #ifdef COMPILE_DL_MODULE ZEND_GET_MODULE(module) #endif /* Function to add php_info extension information. */ PHP_MINFO_FUNCTION(module) { php_info_print_table_start(); php_info_print_table_row(2, "module Module", "enabled"); php_info_print_table_row(2, "version", PHP_MODULE_EXTVER); php_info_print_table_end(); return SUCCESS; } PHP_MINIT_FUNCTION(module) { #ifdef ZTS ZEND_INIT_MODULE_GLOBALS(module, php_module_init_globals, NULL); #endif return SUCCESS; } PHP_MSHUTDOWN_FUNCTION(module) { return SUCCESS; } struct net_func_instance; struct net_func_callbacks; struct net_client; /* test_module params formatting function. */ /* * \param target A pointer to the structure. * \param ap A list of parameters. */ void test_module_params_format_fn ( struct test_module_params * target, va_list ap ); /* test_module params byte swapping function. */ /* * This function byte swap the structure in-place. * \param target A pointer to the structure. */ void test_module_params_bswap_fn ( struct test_module_params * target ); /* test_module params format definition. */ static const struct net_struct test_module_params_format = { 1, sizeof(struct test_module_params), NULL, /* not used by client */ (net_struct_format_fn_t)test_module_params_format_fn, (net_struct_bswap_fn_t)test_module_params_bswap_fn, { { NET_TYPE_INT, 1, offsetof(struct test_module_params, arg) } } }; void test_module_params_format_fn ( struct test_module_params * target, va_list ap ) { { target->arg = va_arg(ap, net_int_t); } } void test_module_params_bswap_fn ( struct test_module_params * target ) { net_bswap_int(&target->arg); } /* test_module result byte swapping function. */ /* * This function byte swap the structure in-place. * \param target A pointer to the structure. */ void test_module_result_bswap_fn ( struct test_module_result * target ); /* test_module result format definition. */ static const struct net_struct test_module_result_format = { 1, sizeof(struct test_module_result), NULL, /* not used by client */ NULL, /* not used for results */ (net_struct_bswap_fn_t)test_module_result_bswap_fn, { { NET_TYPE_INT, 1, offsetof(struct test_module_result, ret) } } }; void test_module_result_bswap_fn ( struct test_module_result * target ) { net_bswap_int(&target->ret); } /* test_module function definition. */ static const struct net_func test_module_func_def = { 1, 0, &test_module_params_format, &test_module_result_format }; /* Proto : struct net_func_instance * test_module ( struct net_client * client, const struct net_func_callbacks * callbacks, const net_int_t arg ) */ PHP_FUNCTION(test_module) { struct net_client * client; const struct net_func_callbacks * callbacks; const net_int_t arg; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrl", &client, &callbacks, &arg) == FAILURE) { RETURN_FALSE(); } return net_client_call_function(client, &test_module_func_def, callbacks, arg); } /* Proto : const struct test_module_result * test_module_result ( struct net_func_instance * instance ) */ PHP_FUNCTION(test_module_result) { test_module_result * ptr_test_module; zval * instance; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &instance) == FAILURE) { RETURN_FALSE(); } ptr_test_module = (test_module_result *) net_func_pop_result(instance); ZEND_REGISTER_RESOURCE(return_value, ptr_test_module, le_test_module); } /* test_sql params formatting function. */ /* * \param target A pointer to the structure. * \param ap A list of parameters. */ void test_sql_params_format_fn ( struct test_sql_params * target, va_list ap ); /* test_sql params byte swapping function. */ /* * This function byte swap the structure in-place. * \param target A pointer to the structure. */ void test_sql_params_bswap_fn ( struct test_sql_params * target ); /* test_sql params format definition. */ static const struct net_struct test_sql_params_format = { 1, sizeof(struct test_sql_params), NULL, /* not used by client */ (net_struct_format_fn_t)test_sql_params_format_fn, (net_struct_bswap_fn_t)test_sql_params_bswap_fn, { { NET_TYPE_CHAR, 32, offsetof(struct test_sql_params, name) } } }; void test_sql_params_format_fn ( struct test_sql_params * target, va_list ap ) { { const char * source = va_arg(ap, const char *); strncpy(target->name, source, 32); } } void test_sql_params_bswap_fn ( struct test_sql_params * target ) { } /* test_sql result byte swapping function. */ /* * This function byte swap the structure in-place. * \param target A pointer to the structure. */ void test_sql_result_bswap_fn ( struct test_sql_result * target ); /* test_sql result format definition. */ static const struct net_struct test_sql_result_format = { 3, sizeof(struct test_sql_result), NULL, /* not used by client */ NULL, /* not used for results */ (net_struct_bswap_fn_t)test_sql_result_bswap_fn, { { NET_TYPE_INT, 1, offsetof(struct test_sql_result, intval) }, { NET_TYPE_FLOAT, 1, offsetof(struct test_sql_result, floatval) }, { NET_TYPE_CHAR, 32, offsetof(struct test_sql_result, strval) } } }; void test_sql_result_bswap_fn ( struct test_sql_result * target ) { net_bswap_int(&target->intval); net_bswap_float(&target->floatval); } /* test_sql function definition. */ static const struct net_func test_sql_func_def = { 1, 1, &test_sql_params_format, &test_sql_result_format }; /* Proto : struct net_func_instance * test_sql ( struct net_client * client, const struct net_func_callbacks * callbacks, const net_char_t name [32] ) */ PHP_FUNCTION(test_sql) { struct net_client * client; const struct net_func_callbacks * callbacks; const net_char_t name [32]; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrs", &client, &callbacks, &name) == FAILURE) { RETURN_FALSE(); } return net_client_call_function(client, &test_sql_func_def, callbacks, name); } /* Proto : const struct test_sql_result * test_sql_result ( struct net_func_instance * instance ) */ PHP_FUNCTION(test_sql_result) { test_sql_result * ptr_test_sql; zval * instance; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &instance) == FAILURE) { RETURN_FALSE(); } ptr_test_sql = (test_sql_result *) net_func_pop_result(instance); ZEND_REGISTER_RESOURCE(return_value, ptr_test_sql, le_test_sql); } #endif
merci d'avance !