如何使用SWIG在PHP中使用std :: vector

时间:2011-12-07 16:08:14

标签: php c++ swig

我正在使用SWIG在PHP中包装C ++ API。我大部分时间都在那里,但我遇到了一个返回向量的函数的问题。标题看起来像这样:

#include <vector>

namespace STF
{
class MyClass
{
    public:
        const std::vector<MyOtherClass> &getList();
};
}

接口文件如下所示:

%include <std_vector.i>
%import "STF_MyOtherClass.i"

%{
    #include "STF_MyOtherClass.h"
    #include "STF_MyClass.h"
%}

%include "STF_MyClass.h"

我似乎能够调用该函数,但它返回的是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 );
    }
}

这非常接近工作。我在SWIG_ZTS_SetPointerZval中的包装器代码中放置了一个断点。当它初始化对象时,它为“stf__myotherclass”执行zend_lookup_class失败(它没有找到clasS)。我不确定为什么找不到这门课。

2 个答案:

答案 0 :(得分:7)

你几乎就在那里,但除了%include <std_vector.i>之外,你还需要这样的东西:

%template (MyVector) std::vector<MyOtherClass>;

这指示SWIG将MyOtherClass的向量公开为目标语言,称为MyVector类型。如果不这样做,SWIG就不知道你想要实例化std::vector的类型,所以它被简化为默认包装。

旁注:

const中的const std::vector<MyOtherClass> getList();不是参考时,是否有理由这样做?我要么将它作为引用并使方法const也(const std::vector<MyOtherClass>& getList() const;)或完全删除const,因为它在那里什么都不做。

答案 1 :(得分:1)

最后,我将把矢量转换为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 );
    }
}

awoodland对我不起作用的%模板。我想这可能是因为我没有将PHP类放在不同的自定义命名空间中。相反,我手动完成了这个并传递了我希望它使用的确切的php类。