2012-04-27 22 views
2

我有一個自定義PHP擴展,它比較二進制數據字符串中的每個字節。如果文件中同一位置的兩個字節都打開(或大於1),則相同位置的輸出將打開。否則關閉。該擴展如下...自定義PHP擴展不適用於5.3

PHP_FUNCTION(compare_memory) 
{ 
    char *memory1, *memory2; 
    int memory1_length, memory2_length, return_length; 
    int length; 
    char *output; 
    int x; 

    zval *param; 

    // MAKE SURE WE HAVE 
    // string, (string_len,), string2, (string2_len) and length 
    if(ZEND_NUM_ARGS() != 2) WRONG_PARAM_COUNT; 

    // GET ARGUMENTS FROM PHP 
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &memory1, &memory1_length, &memory2, &memory2_length) == FAILURE) 
    { 
     return; 
    } 

    if (memory1_length < memory2_length) 
    { 
     length = memory1_length; 
     return_length = memory2_length; 
    } else 
    { 
     length = memory2_length; 
     return_length = memory1_length; 
    } 

    if ((output = emalloc(return_length * sizeof(int))) == NULL) 
    { 
     printf("Error on malloc\n"); 
     return; 
    } 

    // START COMPARING 
    for(x=1;x<length;x++) 
    { 
     if (memory1[x] > 0 && memory2[x] == 1) 
     { 
      output[x] = memory1[x]; 
     } 
    } 

    RETVAL_STRINGL(output, return_length, 1); 
    efree(output); 
} 

我也有一個PHP執行如下...

function compare_memory($data1, $data2) 
{ 
    $pack_one = pack("c", 1); 
    $pack_zero = pack("c", 0); 
    $strlen_data1 = strlen($data1); 
    $strlen_data2 = strlen($data2); 
    if ($strlen_data1 > $strlen_data2) 
    { 
     $strlen = $strlen_data1; 
    } else 
    { 
     $strlen = $strlen_data2; 
    } 
    $output = ""; 

    for($x=0;$x<$strlen;$x++) 
    { 
     if ($strlen_data1 > $x) 
     { 
      $arr = unpack("cc", $data1[$x]); 
      $d1 = $arr["c"]; 
     } else 
     { 
      $d1 = 0; 
     } 

     if ($strlen_data2 > $x) 
     { 
      $arr = unpack("cc", $data2[$x]); 
      $d2 = $arr["c"]; 
     } else 
     { 
      $d2 = 0; 
     } 

     if ($d1 > 0 && $d2 == 1) 
     { 
      $output .= pack("c", $d1); 
     } else 
     { 
      $output .= $pack_zero; 
     } 
    } 

    return $output; 
} 

這種擴展是工作的罰款與PHP 5.0(這我知道是很老)。我們最近升級到5.3,這不再有效。但是PHP的實現呢。

我想在這兩個版本之間已經發生了很多PHP內部API的變化,包括「參數解析API統一將導致某些函數在處理類型雜亂時表現出更嚴格或更差的行爲」。

你能在PHP擴展中看到任何明顯的東西,可能導致它在更新版本的PHP中無法工作嗎?我對C(和PHP API)的知識很少。

+1

擴展名「不工作」的症狀究竟是什麼? – PlasmaHH 2012-04-27 13:23:31

+0

擴展的輸出返回一個字符串,其中所有字節都設置爲on,以獲得最長輸入字符串的長度。 – 2012-04-27 13:33:49

+0

看看violet313s的答案吧,可能是相關的。 – PlasmaHH 2012-04-27 13:37:53

回答

0

我不確定你可以保證emalloc將返回你初始化爲0的內存。您可以嘗試使用ecalloc。 還是自己動手:

if ((output = emalloc(return_length * sizeof(int))) == NULL) 
{ 
    printf("Error on malloc\n"); 
    return; 
} 
memset(output, 0, return_length * sizeof(int)); 


另外,我不認爲emalloc不斷返回NULL

(此外,我不知道爲什麼你從1而不是零for(x=1;x<length;x++)開始,但也許有原因)

+0

究竟是什麼讓你覺得他需要清零內存? – PlasmaHH 2012-04-27 13:20:45

+0

@ [PlasmaHH(http://stackoverflow.com/users/833362/plasmahh)〜從PHP實現推斷,顯然是工作..但正如你指出,OP應該說一點關於它是如何「不工作」 – violet313 2012-04-27 13:22:33

+0

ecalloc完美地工作。它出現在舊版本的slackware上,當使用emalloc時,內核將分配內存零。這不是emalloc打算做的。使用ecalloc來解決問題。感謝您的幫助:) – 2012-06-01 10:56:10