【发布时间】:2011-04-24 16:36:47
【问题描述】:
问题:我使用 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_;
};
我已经使用 SWIG 将这些类包装在 python 中。在我的 python 代码中,我想将 Base 引用向下转换为 Derived。为此,我在 swig .i 文件中写入了一个使用 c++ 进行向下转换的辅助函数:
%inline %{
Derived* CastToDerived(Base* base) {
return static_cast<Derived*>(base);
}
%}
在我的 python 代码中,我称之为向下转换函数:
base = container.GetBase()
derived = CastToDerived(base)
当我这样做时,我收到以下错误:
TypeError: in method 'CastToDerived', argument 1 of type 'Base *'
为什么会发生这种情况?
作为参考,这里是 SWIG 生成的 .cxx 文件的相关位;即原始函数,以及它的python接口化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;
}
任何帮助将不胜感激。
-- 马特
【问题讨论】:
-
GetBase() 生成的代码是什么样的?该错误意味着传递给 CastToDerived 的对象不是正确的类型 - 它是什么类型?
-
为了它的价值,我只是尝试基于上述创建一个示例,使用 swig 1.3.40,我没有收到此错误。
-
太奇怪了……我试着写一些像你的例子一样的东西,克里斯,确实奏效了。正如您所料,我实际上遇到问题的代码不是玩具问题,我只是将其玩具化以使其足够短以适应问题。我当前的解决方法是在我的 c++ 库中定义 CastToDerived 函数,而不是在 .i 文件中的 %inline %{ ... %} 块中。这解决了问题。也许这个细节可能是对正确人的暗示?我仍然希望不将 SWIG 助手添加到我的 c++ 库中。
-
我要做的是使用 -g 编译所有内容,不进行优化,然后单步执行代码以查看 SWIG_ConvertPtr 失败的地方,希望这能给我一个线索来了解正在发生的事情。跨度>
标签: c++ python swig typeerror downcast