【问题标题】:Porting a php5 module to php 7 and zend_string issues when compiling编译时将 php5 模块移植到 php 7 和 zend_string 问题
【发布时间】:2017-01-15 21:07:33
【问题描述】:

我正在将 php5 移植到 php7,但不明白如何正确使用 zend_string,因为它在编译时给了我错误。我关注了phpng guide关于php7的变化。大多数功能我都可以轻松移植,但这个功能让我很头疼。

模块的php5版本如下:

PHP_FUNCTION(swe_houses)
{
char *arg = NULL;
int hsys_len, rc;
char *hsys = NULL;
double tjd_ut, geolat, geolon;
double cusps[37], ascmc[10]; 
int i, houses;
zval *cusps_arr, *ascmc_arr;

if(ZEND_NUM_ARGS() != 4) WRONG_PARAM_COUNT;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ddds",
        &tjd_ut, &geolat, &geolon, &hsys, &hsys_len) == FAILURE) {
    return;
}
if (hsys_len < 1)
    return;

rc = swe_houses(tjd_ut, geolat, geolon, hsys[0], cusps, ascmc);

/* create 2 index array, and 1 assoc array */
array_init(return_value);

MAKE_STD_ZVAL(cusps_arr);
array_init(cusps_arr);

if (hsys[0] == 'G')
    houses = 37;
else
    houses = 13;

for(i = 0; i < houses; i++)
    add_index_double(cusps_arr, i, cusps[i]);

MAKE_STD_ZVAL(ascmc_arr);
array_init(ascmc_arr);
for(i = 0; i < 10; i++)
    add_index_double(ascmc_arr, i, ascmc[i]);

add_assoc_zval(return_value, "cusps", cusps_arr);
add_assoc_zval(return_value, "ascmc", ascmc_arr);
add_assoc_long(return_value, "rc", rc);
}

所以指南说我需要将“char *hsys”替换为“zend_string *hsys = null”。并将“MAKE_STD_ZVAL”功能替换为“ZVAL_NEW_ARR”。在 zend_parse_parameters 函数中,我将“s”参数更改为“S”。

所以最终我将代码更改为如下所示:

PHP_FUNCTION(swe_houses)
{
zend_string *arg = NULL;
size_t hsys_len, rc;
zend_string *hsys = NULL;
double tjd_ut, geolat, geolon;
double cusps[37], ascmc[10]; 
size_t i, houses;
zval *cusps_arr, *ascmc_arr;

if(ZEND_NUM_ARGS() != 4) WRONG_PARAM_COUNT;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dddS",
        &tjd_ut, &geolat, &geolon, &hsys, &hsys_len) == FAILURE) {
    return;
}
if (hsys_len < 1)
    return;

rc = swe_houses(tjd_ut, geolat, geolon, hsys[0], cusps, ascmc);

/* create 2 index array, and 1 assoc array */
array_init(return_value);

/*******************************/
/*      removed for php 7      */
/*   MAKE_STD_ZVAL(cusps_arr); */
/*******************************/

ZVAL_NEW_ARR(cusps_arr);
array_init(cusps_arr);

if (hsys[0] == 'G')
    houses = 37;
else
    houses = 13;

for(i = 0; i < houses; i++)
    add_index_double(cusps_arr, i, cusps[i]);

/*******************************/
/*      removed for php 7      */   
/*    MAKE_STD_ZVAL(ascmc_arr); */
/*******************************/

ZVAL_NEW_ARR(ascmc_arr);
array_init(ascmc_arr);


for(i = 0; i < 10; i++)
    add_index_double(ascmc_arr, i, ascmc[i]);

add_assoc_zval(return_value, "cusps", cusps_arr);
add_assoc_zval(return_value, "ascmc", ascmc_arr);
add_assoc_long(return_value, "rc", rc);
}

但是在编译时它给了我以下错误:

/home/hermes/php-sweph/latest/php-sweph/sweph.c:926:42: error:   
incompatible type for argument 4 of ‘swe_houses’
rc = swe_houses(tjd_ut, geolat, geolon, hsys[0], cusps, ascmc);
                                      ^
In file included from /home/hermes/php-sweph/latest/php- 
sweph/sweph.c:23:0:

/usr/local/include/swephexp.h:742:16: note: expected ‘int’ but argument is       

of type ‘zend_string {aka struct _zend_string}’
ext_def( int ) swe_houses(
            ^
/home/hermes/php-sweph/latest/php-sweph/sweph.c:939:14: error: invalid    
operands to binary == (have ‘zend_string {aka struct _zend_string}’ and        
‘int’)
if (hsys[0] == 'G')

【问题讨论】:

    标签: php c++ php-extension php-7.1


    【解决方案1】:

    首先,zend_stringchar*char[] 完全不同,因此您不能仅通过引用索引来访问元素。这是一个struct,而不是一个数组。

    这就是zend_string:

    struct _zend_string {
        zend_refcounted_h gc;
        zend_ulong        h;                /* hash value */
        size_t            len;
        char              val[1];
    };
    

    我要做的是将hsys 改回char*,这样您就可以使用常规字符串函数并像数组一样引用元素。

    这是我认为可行的示例,我将评论我对此所做的更改。

    PHP_FUNCTION(swe_houses) {
        char *arg = NULL;                 /* char */
        size_t hsys_len, rc;
        char *hsys = NULL;                /* char */
        double tjd_ut, geolat, geolon;
        double cusps[37], ascmc[10]; 
        size_t i, houses;
        zval cusps_arr, ascmc_arr;        /* removed pointer */
    
        if(ZEND_NUM_ARGS() != 4) WRONG_PARAM_COUNT;
    
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ddds",
            &tjd_ut, &geolat, &geolon, &hsys, &hsys_len) == FAILURE) {
            return;
        }
        if (hsys_len < 1)
            return;
    
        rc = swe_houses(tjd_ut, geolat, geolon, hsys[0], cusps, ascmc);
    
        /* create 2 index array, and 1 assoc array */
        array_init(return_value);
    
        /* ZVAL_NEW_ARR(cusps_arr); unneeded */
        array_init(&cusps_arr); /* added & */
    
        if (hsys[0] == 'G')
            houses = 37;
        else
            houses = 13;
    
        for(i = 0; i < houses; i++)
            add_index_double(&cusps_arr, i, cusps[i]); /* added & */
    
        /* ZVAL_NEW_ARR(ascmc_arr); unneeded */
        array_init(&ascmc_arr); /* added & */
    
    
        for(i = 0; i < 10; i++)
            add_index_double(&ascmc_arr, i, ascmc[i]); /* added & */
    
        /* this may cause issues, not sure though */
        add_assoc_zval(return_value, "cusps", &cusps_arr); /* added & */
        add_assoc_zval(return_value, "ascmc", &ascmc_arr); /* added & */
        add_assoc_long(return_value, "rc", rc);
    }
    

    【讨论】:

    • 哇非常非常非常非常感谢你。完全像它应该做的那样工作!你不想知道我有多感激。我试了几天,没想到几周前我的问题会得到答案。所以这个解决方案让我的模块再次正常工作!谢谢谢谢!
    • 我去过那里,相信我。很高兴我能帮上忙。
    猜你喜欢
    • 2011-03-31
    • 2011-05-10
    • 2013-11-26
    • 2011-08-31
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 2013-10-02
    相关资源
    最近更新 更多