我正在使用SWIG在PHP中包装C++ API.我大部分时间都在那里,但我遇到了一个返回向量的函数的问题.标题看起来像这样:
#include <vector>
namespace STF
{
class MyClass
{
public:
const std::vector<MyOtherClass> &getList();
};
}
Run Code Online (Sandbox Code Playgroud)
接口文件如下所示:
%include <std_vector.i>
%import "STF_MyOtherClass.i"
%{
#include "STF_MyOtherClass.h"
#include "STF_MyClass.h"
%}
%include "STF_MyClass.h"
Run Code Online (Sandbox Code Playgroud)
我似乎能够调用该函数,但它返回的是PHP资源而不是对象.具体来说,它是一种类型的资源:"_ p_std__vectorT_STF__MyClass_t".
我怎样才能让它返回一个我可以遍历的对象(最好是使用foreach循环)或者如何迭代这个资源?
更新:
我一直在研究基于我在这里阅读的解决方案:http://permalink.gmane.org/gmane.comp.programming.swig/16817
基本上我试图将矢量转换为python数组:
%typemap(out) std::vector<STF::MyOtherClass>
{
array_init( return_value );
std::vector<STF::MyOtherClass>::iterator itr;
itr = $1.begin();
for( itr; itr != $1.end(); itr++ )
{
zval* tmp;
MAKE_STD_ZVAL( tmp );
SWIG_SetPointerZval( tmp, &*itr, $descriptor(STF::MyOtherClass*), 2 );
add_next_index_zval( return_value, tmp );
}
}
Run Code Online (Sandbox Code Playgroud)
这非常接近工作.我在SWIG_ZTS_SetPointerZval中的包装器代码中放置了一个断点.当它初始化对象时,它为"stf__myotherclass"执行zend_lookup_class失败(它没有找到clasS).我不确定为什么找不到这门课.
你几乎就在那里,但%include <std_vector.i>你也需要这样的东西:
%template (MyVector) std::vector<MyOtherClass>;
Run Code Online (Sandbox Code Playgroud)
这指示SWIG将MyOtherClass目标语言的向量公开为所谓的类型MyVector.如果不这样做,SWIG不知道您想要实例化哪些类型std::vector,因此它被简化为默认包装.
边注:
有你有一个原因const在const std::vector<MyOtherClass> getList();时,它不是一个参考?我要么将它作为引用并使方法const也(const std::vector<MyOtherClass>& getList() const;或)const完全删除,因为它在那里什么都不做.
最后,我将向量转换为 PHP 数组(将其放入 MyOtherClass 的接口文件中):
%typemap(out) const std::vector<STF::MyOtherClass>&
{
array_init( return_value );
std::vector<STF::MyOtherClass>::const_iterator itr;
itr = $1->begin();
for( itr; itr != $1->end(); itr++ )
{
zval* tmp;
STF::MyOtherClass * res = new STF::MyOtherClass( *itr );
MAKE_STD_ZVAL( tmp );
swig_type_info type = *$descriptor(STF::MyOtherClass*);
type.name = (char*)"_p_CustomNamespace\\MyOtherClass";
SWIG_SetPointerZval( tmp, res, &type, 2 );
add_next_index_zval( return_value, tmp );
}
}
Run Code Online (Sandbox Code Playgroud)
林地的%模板不适合我。我认为这可能是因为我没有将 PHP 类放在不同的自定义命名空间中。相反,我手动执行此操作并传入我希望它使用的确切 php 类。