2 Stimmen

Benutzerdefinierte PHP-Erweiterung funktioniert nicht für 5.3

Ich habe eine benutzerdefinierte PHP-Erweiterung, die jedes Byte in einem binären Datenstring vergleicht. Wenn beide Bytes an der gleichen Stelle in der Datei eingeschaltet sind (oder größer als 1), dann wird die Ausgabe an der gleichen Position eingeschaltet. Ansonsten ist sie aus. Die Erweiterung ist wie folgt...

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);
}   

Ich habe auch eine PHP-Implementierung wie folgt...

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;
}

Diese Erweiterung funktionierte problemlos mit PHP 5.0 (das, wie ich weiß, sehr alt ist). Wir haben vor kurzem auf 5.3 aktualisiert und sie funktioniert nicht mehr. Die PHP-Implementierung funktioniert jedoch.

Ich kann mir vorstellen, dass es zwischen den Versionen eine ganze Reihe von Änderungen an der PHP-internen API gegeben hat, darunter auch die Vereinheitlichung der Parameter-Parsing-API, die dazu führt, dass sich einige Funktionen mehr oder weniger strikt verhalten, wenn es um das Jonglieren mit Typen geht.

Können Sie irgendetwas Offensichtliches in der PHP-Erweiterung erkennen, das dazu führen könnte, dass sie in neueren PHP-Versionen nicht funktioniert? Meine Kenntnisse von C (und der PHP-API) sind spärlich.

0voto

violet313 Punkte 1872

Ich bin mir nicht sicher, ob Sie das garantieren können. emalloc gibt Ihnen einen mit Nullen initialisierten Speicher zurück. Sie könnten versuchen, mit ecalloc stattdessen. Oder machen Sie es selbst:

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

Außerdem glaube ich nicht, dass emalloc immer gibt zurück. NULL

(Ich bin mir auch nicht sicher, warum Ihr for(x=1;x<length;x++) beginnt bei 1 statt bei Null, aber vielleicht gibt es dafür einen Grund)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X