2

バイナリ データ文字列の各バイトを比較するカスタム PHP 拡張機能があります。ファイル内の同じ位置にある両方のバイトがオン (または 1 より大きい) の場合、同じ位置の出力がオンになります。それ以外の場合はオフです。拡張子は次のとおりです...

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) に関する私の知識はまばらです。

4

1 に答える 1

0

emallocゼロで初期化されたメモリが返されることを保証できるかどうかはわかりません。代わりにecallocを使用してみてください。または自分でやってください:

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


emalloc また、私は決して戻ってこないと思いますNULL

(またfor(x=1;x<length;x++)、ゼロではなく1から始まる理由もわかりませんが、おそらく理由があります)

于 2012-04-27T13:16:05.810 に答える