2010-05-19 38 views
2

我需要讓我的PHP擴展返回一個對象數組,但我似乎無法弄清楚如何執行此操作。如何從PHP擴展返回C++對象數組

我有一個用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

你怎麼知道它正在返回(成功),而不是在RETURN_NULL調用期間segfaulting? – Zak 2010-05-19 19:06:29

+0

啊,我的錯。我已經刪除了RETURN_NULL();調用並仍然獲得段錯誤。這條線意外地以此代碼結束。 – 2010-05-19 20:07:42

回答

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