c ++ — портирование модуля php5 на php 7 и проблемы с zend_string при компиляции

Я портирую php5 на php7, но не понимаю, как правильно использовать zend_string, так как это дает мне ошибки при компиляции. Я следовал за руководство phpng об изменениях в 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')

2

Решение

Обо всем по порядку, zend_string совсем не похоже на char* или же 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);
}
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]