2

PHP 拡張機能でオブジェクトの配列を返す必要がありますが、これを行う方法がわかりません。

GraphC++ で記述されたオブジェクトがあります。Graph.getNodes()を返しますstd::map<int, Node*>。これが私が現在持っているコードです:

struct node_object {
        zend_object std;
        ノード *ノード;
};

zend_class_entry *node_ce;

それから

PHP_METHOD(グラフ、getNodes)
{
        グラフ *グラフ;
        GET_GRAPH(graph, obj) // グラフを作成するために作成したマクロ

        node_object* n;
        zval* node_zval;

        if (obj == NULL) {
                RETURN_NULL();
        }   

        if (object_init_ex(node_zval, node_ce) != 成功) {
                RETURN_NULL();
        }   


        std::map nodes = graph->getNodes();

        array_init(戻り値);

        for (std::map::iterator i = nodes.begin(); i != nodes.end(); ++i) {
                php_printf("X");
                n = (node_object*) zend_object_store_get_object(node_zval TSRMLS_CC);
                n->node = i->second;
                add_index_zval(return_value, i->first, node_zval);
        }

        php_printf("]");
}

実行するphp -r '$g = new Graph(); $g->getNodes();'と、出力が得られます

XX]Segmentation fault

つまり、getNodes() 関数は 2 つのノード リストを正常にループし、リターンしてから segfaults を返します。私は何を間違っていますか?

4

1 に答える 1

5

MAKE_STD_ZVAL(node_zval) が必要でした。このコードの二次的な問題は、この zval ポインターを再利用していたため、以前のすべての zval が上書きされ、同じオブジェクトでいっぱいの配列になってしまうことでした。これを改善するために、ループごとに node_zval を初期化します。最終的なコードは次のとおりです。

PHP_METHOD(グラフ、getNodes)
{
        グラフ *グラフ;
        GET_GRAPH(graph, obj) // グラフを作成するために作成したマクロ

        node_object* n;
        zval* node_zval;

        if (obj == NULL) {
                RETURN_NULL();
        }   

        std::map nodes = graph->getNodes();

        array_init(戻り値);

        for (std::map::iterator i = nodes.begin(); i != nodes.end(); ++i) {
                MAKE_STD_ZVAL(node_zval);
                if (object_init_ex(node_zval, node_ce) != 成功) {
                        RETURN_NULL();
                }   

                n = (node_object*) zend_object_store_get_object(node_zval TSRMLS_CC);
                n->node = i->second;
                add_index_zval(return_value, i->first, node_zval);
        }
}
于 2010-05-19T21:02:17.720 に答える