所以我玩的是Python,C++ 0x和SWIG 2。我有一个标题,看起来像这样:
#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进行必要的表查找并生成我想要的对象,但我还没有找到它。
dynamic_cast
(或者)
如果在SWIG中这种行为(特别是从保存基类指针的C++容器类中检索最派生的代理)是不可能的,那么SIP或其他Python包装器生成器呢?
更新#2
由于SIP4看起来在合理地检索包装对象方面效果更好,所以我将再次更改问题。查看下面我的自我回答,了解我当前问题的详细信息。我还是会接受一个好的答案,因为我更喜欢原来的SWIG问题,但我的新问题,基本上是:
-
我怎样才能理智地对待周围的包装物呢
shared_ptr
而不是原始指针?如果有用的话,我所有的类都是子类
enable_shared_from_this
并公开一个适当的函数来获取共享指针。
-
如何使用SIP4的构建系统(Makefile generator或distutils extension)构建我的小示例项目,而不必首先生成并安装共享库或手动编辑生成的Makefile?