2014-09-30 219 views
0

我正在研究一個PHP擴展,並希望讓PHP返回一個結構。但它總是造成核心轉儲。我的步驟是:PHP擴展返回結構

  1. ./ext_skel --extname=test

  2. ./configure --enable-test

  3. php_test.h,添加:

    typedef struct mydata { 
        int m_id; 
        int m_age; 
    }MYDATA; 
    PHP_FUNCTION(wrap_getMydata);` 
    
  4. 在test.c的,加:

    #define MY_RES_NAME "my_resource"; 
    static int my_resource_descriptor; 
    PHP_FE(wrap_getMydata, NULL) 
    ... 
    ZEND_MINIT_FUNCTION(test) 
    { 
        /* If you have INI entries, uncomment these lines 
        REGISTER_INI_ENTRIES(); 
        */ 
        resid = zend_register_list_destructors_ex(NULL, NULL, MY_RES_NAME, module_number); 
    
        return SUCCESS; 
    } 
    
    PHP_FUNCTION(test_getMydata) 
    
    { 
        zval* res; 
        long int a, b; 
        long int result; 
    
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &a, &b) == FAILURE) { 
         return; 
        } 
        MYDATA objData; 
        objData.m_id = a; 
        objData.m_age = b; 
        ZEND_REGISTER_RESOURCE(res, &objData, resid); 
        RETURN_RESOURCE(res); 
    } 
    
  5. 附加:var_dump(test_getMydata(3,4))test.php

  6. 然後make; make install; ./php test.php,它打印:

    Functions available in the test extension: 
    confirm_wrap_compiled 
    test_getMydata 
    Congratulations! You have successfully modified ext/wrap/config.m4. Module wrap is now compiled into PHP. 
    Segmentation fault (core dumped) 
    
  7. $ gdb ../../bin/php core.23310

    Loaded symbols for /home/user1/php/php-5.2.17/lib/php/extensions/no-debug-non-zts-20060613/test.so 
    #0 0x00000000006388ad in execute (op_array=0x2a9569bd68) at /home/user1/php/php-5.2.17/Zend/zend_vm_execute.h:92 
    92      if (EX(opline)->handler(&execute_data TSRMLS_CC) > 0) {` 
    

有人可以給些幫助?

+0

有沒有人提供一些線索? – 2014-09-30 13:51:09

+0

我認爲它的一個問題與您的變量範圍 嘗試類似: ' MYDATA * objData; objData = emalloc(sizeof(objData)); objData-> m_id = a; objData-> m_age = b; ZEND_REGISTER_RESOURCE(return_value,res,resid); ' – 2015-05-08 17:48:28

回答

0

遺憾在評論壞格式 - 這是我最後的答案:

我不得不重新命名testenter code herehjtest擴展 - 寄託都還應當符合幾乎與公佈的樣本。

TL;博士 - 問題 - 和SIGSEGV你的樣品中是要註冊的資源給本地變量objData - 在函數結束至極且不能再 - 你需要使用emalloc得到一塊的動態記憶 - 這將持有你的MYDATA

從那裏你有一個資源 - 綁定到一些dyn。內存,您需要註冊一個dtor功能 - 因此您可以發佈/ efree您的註冊內存。

希望有幫助。

解決上述問題 - modifie你的資源註冊這樣的:

MYDATA * objData=emalloc(sizeof(MYDATA)); 
    objData->m_id = a; 
    objData->m_age = b; 
    ZEND_REGISTER_RESOURCE(return_value, objData, resid); 

,並添加一個析構函數: ... MINIT

resid = zend_register_list_destructors_ex(resdtor, NULL, MY_RES_NAME, module_number); 

static void resdtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) 
    { 
     MYDATA *res = (MYDATA*)rsrc->ptr; 
     if (res) { 
      efree(res); 
     } 
    } 

爲完整樣品見本GIST:https://gist.github.com/hjanuschka/3ed54e66f017a379cf25