我需要让我的PHP扩展返回一个对象数组,但我似乎无法弄清楚如何做到这一点。
我有一个用C ++编写的Graph
对象。 Graph.getNodes()
会返回std::map<int, Node*>
。这是我目前的代码:
struct node_object { zend_object std; Node *node; }; zend_class_entry *node_ce;
然后
PHP_METHOD(Graph, getNodes) { Graph *graph; GET_GRAPH(graph, obj) // a macro I wrote to populate graph node_object* n; zval* node_zval; if (obj == NULL) { RETURN_NULL(); } if (object_init_ex(node_zval, node_ce) != SUCCESS) { RETURN_NULL(); } std::map nodes = graph->getNodes(); array_init(return_value); 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节点列表成功循环,返回,然后是段错误。我做错了什么?
答案 0 :(得分:5)
我只需要MAKE_STD_ZVAL(node_zval)。这段代码的第二个问题是我重用了这个zval指针,因此覆盖了每个先前的zval,最后得到了一个完整相同对象的数组。为了解决这个问题,我为每个循环初始化node_zval。这是最终的代码:
PHP_METHOD(Graph, getNodes) { Graph *graph; GET_GRAPH(graph, obj) // a macro I wrote to populate graph node_object* n; zval* node_zval; if (obj == NULL) { RETURN_NULL(); } std::map nodes = graph->getNodes(); array_init(return_value); for (std::map::iterator i = nodes.begin(); i != nodes.end(); ++i) { MAKE_STD_ZVAL(node_zval); if (object_init_ex(node_zval, node_ce) != SUCCESS) { 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); } }