如何访问SWIG Python生成的抽象c ++类方法?

时间:2014-01-30 15:37:56

标签: python c++ swig

这可能是我想念的简单但我无法找到任何解释。

给定一个抽象类,它在别处实现,其接口由导出函数提供:

class IFoo {
public:
    virtual ~IFoo(){}
    virtual void bar()=0;
};

extern IFoo* get_interface();

在c ++中我会用它作为:

IFoo* foo = get_interface();
foo->bar();

如果我SWIG这个,我可以导入模块并将get_interface()分配给变量:

import myfoo
foo = myfoo.get_interface()

但我无法访问foo.bar():

>>> foo.bar()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'SwigPyObject' object has no attribute 'bar'

我错过了什么?

谢谢!


如果上面的碎片不够清晰,那么这就是完整的事情:

* .i文件:

%module myfoo
#define SWIG_FILE_WITH_INIT

%include "myfoo.h"
%{
#include "myfoo.h"
%}

myfoo.h标题:

class IFoo {
public:
    virtual ~IFoo(){}
    virtual void bar()=0;
    virtual void release()=0;
};

extern IFoo* get_interface();

实施文件(myfoo.cpp)

#include "myfoo.h"
#include <iostream>

class Foo : public IFoo {
public:
    Foo(){}
    ~Foo(){}
    void bar();
    void release();
};

void Foo::bar() {
    cout << "Foo::bar()..." << endl;
}

void Foo::release() {
    delete this:
}

IFoo* get_interface() {
    return new Foo();
}

2 个答案:

答案 0 :(得分:2)

我发现了问题。我在生成Ruby扩展的构建系统中有这个。当我决定添加Python绑定时,我刚刚添加了一个新的(Xcode)目标,就像我为Ruby扩展做的那样。我没有意识到swig还生成了带有所有初始化代码的模块 .py文件(与Ruby不同)。一旦我发现了,我只是将生成的python文件与扩展动态库文件一起移动并导入它。这一切现在都有效。

我发现通过手动创建上面的myfoo代码(而不是运行我的构建系统,它忽略了额外的myfoo.py文件)。一旦我手动操作swig,我注意到它不仅产生了myfoo_wrapp.cpp,还产生了myfoo.py。

感谢您的努力。为了将来参考,这与导演无关(我不是想创建一个双向接口)。它根本不知道swig生成的额外python初始化代码。

在:

myfoo.i
myfoo.h
myfoo.cpp

>swig -c++ -python myfoo.i

后:

myfoo.i
myfoo.h
myfoo.cpp
myfoo.py    <== Missed this one
myfoo_wrap.cxx

答案 1 :(得分:0)

检查您的模块的.i文件中是否已打开“导演”:

%module(directors="1") myfoo

这将在34.5 "Cross language polymorphism" of SWIG docs部分中讨论。如果它已经开启,请发表评论,我会仔细看看。