8

オブジェクトメソッドが配列を返す必要がある PHP 拡張機能を開発していますzval

メソッドは次のようになります。

ZEND_METHOD(myObject, myMethod)
{
    zval **myArrayProperty;
    if (zend_hash_find(Z_OBJPROP_P(getThis()), "myArrayProperty", sizeof("myArrayProperty"), (void **) &myArrayProperty) == FAILURE) {
        RETURN_FALSE;
    }
    RETURN_ZVAL(*myArrayProperty, 1, 0);
}

コードは正常に動作し、期待どおりに動作します。オブジェクトのmyArrayProperty. ただし、プロセスを最適化したいと思います。

myArrayProperty非常に大きくなる可能性がある配列を格納します。そして、RETURN_ZVAL()マクロは値を返すためにその配列を複製します。複製プロセスでは、メモリを取得してすべての配列値をコピーするのにかなりの時間がかかります。同時に、返された配列は通常、読み取り専用操作に使用されます。myArrayPropertyしたがって、適切な最適化は、参照カウントで PHP のメカニズムを使用し、コンテンツを複製しないことです。むしろ、私はそれを増やしrefcountて、myArrayPropertyそれへのポインタを返すだけです。これは、PHP 拡張機能で変数を操作するときに通常使用されるのと同じ戦術です。

ただし、それを行う方法はないようです-PHP拡張関数から値を返すには、値を複製する必要があります。関数シグネチャを参照によって戻り値に変更することはオプションではありません。これは、プロパティと戻り値をリンクするためです。つまり、後で戻り値を変更すると、プロパティも変更されます。それは容認できる行為ではありません。

PHP の同じコード:

function myMethod() {
{
    return $this->myArrayProperty;
}

参照カウントメカニズムによって最適化されます。そのため、何かを見逃した場合に備えて、StackOverflow でこの質問をしています。

では、配列をメモリにコピーせずに、PHP 拡張機能の関数から配列を返す方法はありますか?

4

3 に答える 3

0

PHP < 5.6 にはアクセスできませんが、問題は値がコピーされることだけだと思います。確実に確認するには、問題の定義をコードで検索する必要があります。

つまり、次のことを試すことができる可能性があります。

 zval *arr;
 MAKE_STD_ZVAL(arr);
 array_init(arr);
 // Do things to the array.
 RETVAL_ZVAL(arr, 0, 0);
 efree(arr);

これは、使い方を誤ると危険です。独自の一時コンテナーで使用する場合、問題はわかりません。

おそらく、戻り値を直接操作することもできますが、これはより良いアプローチかもしれません。おそらく初期化して、最初にポインターとして渡します。

このように戻り結果をラップできます。参照を試すこともできます。

于 2015-10-26T17:09:17.833 に答える
-1

このようなコードを書いてからしばらく経ちました…</p>

だから、私は以下のコードで何をしますか: 1)。refcount を明示的に増加させる 2)。コピーせずに zval を返す

ZEND_METHOD(myObject, myMethod)
{
    zval **myArrayProperty;

    if (zend_hash_find(Z_OBJPROP_P(getThis()), "myArrayProperty", sizeof("myArrayProperty"), (void **) &myArrayProperty) == FAILURE) {
        RETURN_FALSE;
    }

    Z_ADDREF_PP(myArrayProperty);
    RETURN_ZVAL(*myArrayProperty, 0, 0);
}
于 2013-07-24T21:05:46.517 に答える