SIP4中的共享指针和构建(是:SWIG / python中的动态转换?)

时间:2010-07-09 22:42:45

标签: c++ python c++11 swig

所以我正在玩Python,C ++ 0x和SWIG 2.0。我有一个看起来像这样的标题:

#include <string>
#include <iostream>
#include <memory>
using namespace std;

struct Base {
  virtual string name();
  int foo;
  shared_ptr<Base> mine;
  Base(int);  
  virtual ~Base() {}
  virtual void doit(shared_ptr<Base> b) {
    cout << name() << " doing it to " << b->name() << endl;
    mine = b;
  }
  virtual shared_ptr<Base> getit() {
    return mine;
  }
};

struct Derived : Base {
  virtual string name();
  int bar;
  Derived(int, int);
};

同时,界面文件如下所示:

%module(directors="1") foo
%feature("director");

%include <std_string.i>

%include <std_shared_ptr.i>
%shared_ptr(Base)
%shared_ptr(Derived)

%{
#define SWIG_FILE_WITH_INIT
#include "foo.hpp"
%}

%include "foo.hpp"

我的Python会话就是这样:

>>> import foo
>>> b = foo.Base(42)
>>> d = foo.Derived(23,64)
>>> b.doit(d)
Base doing it to Derived 
>>> g = b.getit()
>>> g
<foo.Base; proxy of <Swig Object of type 'std::shared_ptr< Base > *' at 0x7f7bd1391930> >
>>> d
<foo.Derived; proxy of <Swig Object of type 'std::shared_ptr< Derived > *' at 0x7f7bd137ce10> >
>>> d == g
False
>>> d is g
False
>>> d.foo == g.foo
True
>>> d.bar
64
>>> g.bar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Base' object has no attribute 'bar'

我似乎无法弄清楚如何在这里检索“原始”代理对象。我必须为每个基类生成一个函数来执行dynamic_pointer_cast吗?如果是这样,在Python中实现了什么Director子类?

我感觉有一个开关或功能我可以在这里开启以获得SWIG进行必要的表查找并生成我想要的对象,但我还没有找到它。

(注意:如果我使用原始指针而不是共享指针,行为是相似的,我无法弄清楚如何将SWIG转移到dynamic_cast那些)

更新

如果这种行为(具体来说,从保存指向基类的C ++容器类中检索派生最多的代理)在SWIG中是不可能的,那么SIP或其他一些Python的包装器生成器怎么样呢? / p>

更新#2

由于SIP4看起来效果更好,只要合理地检索包装对象,我将再次更改问题。请查看下面的我自己的答案,了解我当前的问题。我仍然会接受原SWIG问题的一个很好的答案,因为我总体上更喜欢它,但我的新问题基本上是:

  • 如何才能在shared_ptr s而不是原始指针周围处理包装器?如果它有帮助,我的所有类都从它们的通用基类中继承enable_shared_from_this并公开一个适当的函数来获取共享指针。

  • 如何使用SIP4的构建系统(Makefile生成器或distutils扩展)构建我的小示例项目,而无需先生成和安装共享库或手动编辑生成的Makefile?

1 个答案:

答案 0 :(得分:0)

为了(部分地)回答我自己的问题,SIP似乎做了正确的事情,对于C ++“Derived”类以及Python级子类 - 至少在我使用原始指针时。

看起来我需要弄清楚如何让它与shared_ptr一起使用(看起来不像SWIG中的%include <std_shared_ptr.i>那么简单。)

此外,两个SIP“构建系统”选项(Makefile生成器和distutils扩展)似乎有点奇怪。他们的手册中的任何一个例子都没有“正常工作” - 看起来他们希望很明显你应该编译和安装你正在尝试的小Hello World库的库/包含路径中的共享库和头文件包装。也许有一个“我只是想在这里构建和运行这个自包含的东西”选项,我错过了,但即使python setup.py build_ext --inplace也失败了,因为它无法找到我已放置的包裹标题我知道当前目录,这显然是一个令人困惑的地方。