Sup*_*ric 5 c++ python swig typeerror downcast
问题:我使用SWIG在python中包装了一些c ++代码.在python方面,我想采用一个包装的c ++指针并将其向下转换为指向子类的指针.我在SWIG .i文件中添加了一个新的c ++函数来执行此向下转换,但是当我从python调用它时,我得到一个TypeError.
以下是详细信息:
我有两个c ++类,Base和Derived.Derived是Base的子类.我有一个第三类,Container,它包含一个Derived,并提供了一个访问器.访问器将Derived作为const Base&返回,如下所示:
class Container {
public:
const Base& GetBase() const {
return derived_;
}
private:
Derived derived_;
};
Run Code Online (Sandbox Code Playgroud)
我使用SWIG在python中包装了这些类.在我的python代码中,我想将Base引用向下转换为Derived.为此,我在swig .i文件中写了一个c ++中的辅助函数,它执行向下转换:
%inline %{
Derived* CastToDerived(Base* base) {
return static_cast<Derived*>(base);
}
%}
Run Code Online (Sandbox Code Playgroud)
在我的python代码中,我称之为向下转换函数:
base = container.GetBase()
derived = CastToDerived(base)
Run Code Online (Sandbox Code Playgroud)
当我这样做时,我收到以下错误:
TypeError: in method 'CastToDerived', argument 1 of type 'Base *'
Run Code Online (Sandbox Code Playgroud)
为什么会发生这种情况?
作为参考,这里是SWIG生成的.cxx文件的相关位; 即原始函数,以及它的python-interface-ified doppelganger:
Derived* CastToDerived(Base* base) {
return static_cast<Derived*>(base);
}
// (lots of other generated code omitted)
SWIGINTERN PyObject *_wrap_CastToDerived(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
Base *arg1 = (Base *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
Derived *result = 0 ;
if (!PyArg_ParseTuple(args,(char *)"O:CastToDerived",&obj0)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Base, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CastToDerived" "', argument " "1"" of type '" "Base *""'");
}
arg1 = reinterpret_cast< Base * >(argp1);
result = (Derived *)CastToDerived(arg1);
resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Derived, 0 | 0 );
return resultobj;
fail:
return NULL;
}
Run Code Online (Sandbox Code Playgroud)
任何帮助将不胜感激.
- 马特
正如我上面评论的,这似乎适用于 swig 1.3.40。
这是我的文件:
频道:
#include <iostream>
class Base {};
class Derived : public Base
{
public:
void f() const { std::cout << "In Derived::f()" << std::endl; }
};
class Container {
public:
const Base& GetBase() const {
return derived_;
}
private:
Derived derived_;
};
Run Code Online (Sandbox Code Playgroud)
词
%module c
%{
#define SWIG_FILE_WITH_INIT
#include "c.h"
%}
%inline %{
Derived* CastToDerived(Base* base) {
return static_cast<Derived*>(base);
}
%}
class Base
{
};
class Derived : public Base
{
public:
void f() const;
};
class Container {
public:
const Base& GetBase() const;
};
Run Code Online (Sandbox Code Playgroud)
测试.py
import c
container = c.Container()
b = container.GetBase()
d = c.CastToDerived(b)
d.f()
print "ok"
Run Code Online (Sandbox Code Playgroud)
一次跑步:
$ swig -c++ -python c.i
$ g++ -fPIC -I/usr/include/python2.6 -c -g c_wrap.cxx
$ g++ -shared -o _c.so c_wrap.o
$ python ctest.py
In Derived::f()
ok
Run Code Online (Sandbox Code Playgroud)