代码之家  ›  专栏  ›  技术社区  ›  kenm

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

  •  3
  • kenm  · 技术社区  · 16 年前

    所以我玩的是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?

    1 回复  |  直到 16 年前
        1
  •  0
  •   kenm    16 年前

    为了(部分地)回答我自己的问题,SIP看起来是正确的,无论是对于C++的“派生类”还是对于Python级子类,至少在使用原始指针时都是正确的。

    看来我得想办法让它工作了 shared_ptr s(看起来不像 %include <std_shared_ptr.i> 大口)。

    另外,SIPs的“构建系统”选项(Makefile generator和distutils extension)似乎都有点奇怪。他们手册中的两个例子都“不管用”——看起来他们希望很明显,您应该在您的库中编译并安装一个共享库和头文件/包含您试图包装的小Hello World库的路径。也许有一个“我只想在这里构建和运行这个自包含的东西”的选项我错过了,但是 python setup.py build_ext --inplace 失败,因为它找不到我放置的包装头