使用 swig 继承 c++ 时出错
error in inheritance c++ using swig
我有一个由 swig 包装并由 python 使用的 c++ 代码。
我想在 C++ 代码中创建一种 运行 回调 python 代码的方法。
所以我创建了一个 "abstract" class (它还不是抽象的)并且我在 .i 文件中用 c++ 将它分类。
这是我写的一些代码片段
.h 文件
class Listener {
public:
Listener();
virtual void register_new();
virtual void run(Msg &m);
virtual ~Listener();
};
.i 文件
%feature("director") PyListener;
using namespace std;
%{
#include "../core/listener.h"
%}
%include "../core/listener.h"
class PyListener : public Listener {
PyObject * function;
public:
PyListener() {};
PyListener(PyObject * func) : function(func) {};
void register_new() {Py_XINCREF(function);};
~PyListener () {Py_XDECREF(function);};
void run(Msg &m) {
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
PyObject *pValue = PyCObject_FromVoidPtr((void*)&m,NULL);
PyObject *pArgs = PyTuple_New(1);
PyTuple_SetItem(pArgs, 0, pValue);
PyObject_CallObject(function, pArgs);
PyGILState_Release(gstate);
};
};
但在编译期间得到
/bin/sh ../../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I../.. -I. -I./../core -I./../../../include -I/opt/regression/usr/include/ -I./../../include_dep/ -I/usr/include/python2.6 -fPIC -g -O2 -MT sim_wrap.lo -MD -MP -MF .deps/sim_wrap.Tpo -c -o sim_wrap.lo sim_wrap.cxx
libtool: compile: g++ -DHAVE_CONFIG_H -I. -I../.. -I. -I./../core -I./../../../include -I/opt/regression/usr/include/ -I./../../include_dep/ -I/usr/include/python2.6 -fPIC -g -O2 -MT sim_wrap.lo -MD -MP -MF .deps/sim_wrap.Tpo -c sim_wrap.cxx -fPIC -DPIC -o .libs/sim_wrap.o
sim_wrap.cxx: In function ‘PyObject* _wrap_new_PyListener__SWIG_0(PyObject*, PyObject*)’:
sim_wrap.cxx:36391: error: ‘PyListener’ was not declared in this scope
sim_wrap.cxx:36391: error: ‘result’ was not declared in this scope
sim_wrap.cxx:36394: error: expected primary-expression before ‘)’ token
sim_wrap.cxx:36394: error: expected ‘;’ before ‘new’
...
由于您同时声明和定义了一个新的 class,因此您需要将其包含在 SWIG 界面的 %inline
中,例如
%inline %{
class PyListener : public Listener {
PyObject * function;
public:
PyListener() {};
PyListener(PyObject * func) : function(func) {};
void register_new() {Py_XINCREF(function);};
~PyListener () {Py_XDECREF(function);};
void run(Msg &m) {
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
PyObject *pValue = PyCObject_FromVoidPtr((void*)&m,NULL);
PyObject *pArgs = PyTuple_New(1);
PyTuple_SetItem(pArgs, 0, pValue);
PyObject_CallObject(function, pArgs);
PyGILState_Release(gstate);
};
};
%}
这会导致 SWIG 不仅包装类型,还会将 declaration/definition 传递给生成的 C++ 代码。这是必需的,因为 PyListener
特定于您的 SWIG 接口,因此在您的任何其他头文件中都不知道。
我有一个由 swig 包装并由 python 使用的 c++ 代码。 我想在 C++ 代码中创建一种 运行 回调 python 代码的方法。 所以我创建了一个 "abstract" class (它还不是抽象的)并且我在 .i 文件中用 c++ 将它分类。
这是我写的一些代码片段
.h 文件
class Listener {
public:
Listener();
virtual void register_new();
virtual void run(Msg &m);
virtual ~Listener();
};
.i 文件
%feature("director") PyListener;
using namespace std;
%{
#include "../core/listener.h"
%}
%include "../core/listener.h"
class PyListener : public Listener {
PyObject * function;
public:
PyListener() {};
PyListener(PyObject * func) : function(func) {};
void register_new() {Py_XINCREF(function);};
~PyListener () {Py_XDECREF(function);};
void run(Msg &m) {
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
PyObject *pValue = PyCObject_FromVoidPtr((void*)&m,NULL);
PyObject *pArgs = PyTuple_New(1);
PyTuple_SetItem(pArgs, 0, pValue);
PyObject_CallObject(function, pArgs);
PyGILState_Release(gstate);
};
};
但在编译期间得到
/bin/sh ../../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I../.. -I. -I./../core -I./../../../include -I/opt/regression/usr/include/ -I./../../include_dep/ -I/usr/include/python2.6 -fPIC -g -O2 -MT sim_wrap.lo -MD -MP -MF .deps/sim_wrap.Tpo -c -o sim_wrap.lo sim_wrap.cxx
libtool: compile: g++ -DHAVE_CONFIG_H -I. -I../.. -I. -I./../core -I./../../../include -I/opt/regression/usr/include/ -I./../../include_dep/ -I/usr/include/python2.6 -fPIC -g -O2 -MT sim_wrap.lo -MD -MP -MF .deps/sim_wrap.Tpo -c sim_wrap.cxx -fPIC -DPIC -o .libs/sim_wrap.o
sim_wrap.cxx: In function ‘PyObject* _wrap_new_PyListener__SWIG_0(PyObject*, PyObject*)’:
sim_wrap.cxx:36391: error: ‘PyListener’ was not declared in this scope
sim_wrap.cxx:36391: error: ‘result’ was not declared in this scope
sim_wrap.cxx:36394: error: expected primary-expression before ‘)’ token
sim_wrap.cxx:36394: error: expected ‘;’ before ‘new’
...
由于您同时声明和定义了一个新的 class,因此您需要将其包含在 SWIG 界面的 %inline
中,例如
%inline %{
class PyListener : public Listener {
PyObject * function;
public:
PyListener() {};
PyListener(PyObject * func) : function(func) {};
void register_new() {Py_XINCREF(function);};
~PyListener () {Py_XDECREF(function);};
void run(Msg &m) {
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
PyObject *pValue = PyCObject_FromVoidPtr((void*)&m,NULL);
PyObject *pArgs = PyTuple_New(1);
PyTuple_SetItem(pArgs, 0, pValue);
PyObject_CallObject(function, pArgs);
PyGILState_Release(gstate);
};
};
%}
这会导致 SWIG 不仅包装类型,还会将 declaration/definition 传递给生成的 C++ 代码。这是必需的,因为 PyListener
特定于您的 SWIG 接口,因此在您的任何其他头文件中都不知道。