与指针有关的 SWIG 问题

Posted

技术标签:

【中文标题】与指针有关的 SWIG 问题【英文标题】:SWIG issue with pointers 【发布时间】:2013-07-17 18:45:15 【问题描述】:

我在使用 SWIG 包装 C++ 类的成员时遇到问题。

我有一个类,它有一个返回 map<int, postLib::nastran::element> 的方法。

接口文件中的类postLib::nastran::element是:

class element 
public:
    element(void) ;
    element( const element &in) ;
    ~element(void) ;

    // data manipulation
    %feature("docstring", "getType()->int\n\tReturns an id corresponding to the TYPE of FE element") getType;
    int getType(void) const ;
    std::string  getTypeName(void) const ;
    int getNbrNodes(void) const ;
    int getNode(int index) const ;

    /*
    %extend 
            std::set<int>  getNodes(void) 
            const std::set<int> *siList;

            siList = &$self->getNodes();
            return *siList;
            
    */
 ; //class element

我的方法是这样的:

PyObject * getEls(void) 
    std::map<int, postLib::nastran::element> els = $self->getElements();
    std::map<int, postLib::nastran::element>::iterator it;
    //PyObject * result = PyDict_New();
    PyObject * result = PyList_New(els.size());
    for (std::map<int, postLib::nastran::element>::iterator it=els.begin(); it!=els.end(); ++it) 
        PyObject * k = Py_BuildValue("i", (it->first)-1);
        postLib::nastran::element * e = &(it->second);
        //PyObject * v = Py_BuildValue("i", &(it->second));
        PyObject *v = SWIG_NewPointerObj((void *)e, SWIGTYPE_p_postLib__nastran__element, SWIG_POINTER_OWN);
        //PyDict_SetItem(result, k, v);
        PyList_SetItem(result, (it->first)-1, v );
        std::cout << typeid(&it->second).name()  << std::endl;
    
    return result;

当我从 Python 对元素实例调用 getType() 方法时,我收到以下错误消息:

pure virtual method called

元素类继承自另一个更通用的元素类,该元素类将 getType 定义为虚拟。

有什么想法吗?

提前致谢。

【问题讨论】:

【参考方案1】:

我从来没有在 Python 语言中使用过 swig,但是我在制作 Java 包装器时遇到了这个错误,希望它是一样的。

当您从 Python 调用 getType 成员方法时会引发此错误,因为它是 C++ 纯虚方法,这意味着它没有实现并且旨在被子类覆盖/实现。所以基本上从 Python 中你调用了一个未实现的方法。

postLib::nastran::element 是否将方法声明为虚拟且等于 0,类似于:

virtual int getType(void) const = 0;

如果是这样,那么它是纯虚拟的,并且在您的 .i 文件中没有以这种方式声明它。当 SWIG 遇到具有纯虚方法的类时,它不会为该类型生成构造函数(因为您无法实例化缺少实现的东西)。

如果该方法是纯虚拟的,那么该类将被子类化。 Swig 可以使用 directors 功能来做到这一点,因此您可以从 Python 扩展该 C++ 类并使用它。

【讨论】:

以上是关于与指针有关的 SWIG 问题的主要内容,如果未能解决你的问题,请参考以下文章

将外部指针包装到 SWIG 数据结构中

SWIG 不接受指针参数的包装对象

带有指针的C结构,如何Swig?

SWIG:无法使用双指针访问构造函数

SWIG C++ Python:通过引用或指针包装 int

SWIG 3 中文手册——5. SWIG 基础知识