gpt4 book ai didi

c++ - 如何从 python SWIG 包装器向下转换 c++ 对象?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:41:54 25 4
gpt4 key购买 nike

问题:我使用 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 接口(interface)化的分身:

  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;
}

如有任何帮助,我们将不胜感激。

-- 马特

最佳答案

正如我在上面评论的那样,这似乎适用于 swig 1.3.40。

这是我的文件:

c.h:

#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_;
};

c.i

%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;
};

ctest.py

import c

container = c.Container()
b = container.GetBase()
d = c.CastToDerived(b)
d.f()
print "ok"

一次运行:

$ 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

关于c++ - 如何从 python SWIG 包装器向下转换 c++ 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3921294/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com