【问题标题】:SWIG, boost shared pointers and inheritanceSWIG,提升共享指针和继承
【发布时间】:2011-06-10 05:59:57
【问题描述】:

我在 SWIG、共享指针和继承方面遇到问题。

我正在创建各种相互继承的 c++ 类,使用 提升共享指针来引用它们,然后包装这些共享 使用 SWIG 创建 Python 类的指针。

我的问题如下:

  • B 是 A 的子类
  • sA 是指向 A 的共享指针
  • sB 是指向 B 的共享指针
  • f(sA) 是一个函数,需要一个指向 A 的共享指针

  • 如果我将 sB 传递给 f(),则会引发错误。

  • 此错误仅发生在 python 级别。
  • 在 C++ 级别,我可以毫无问题地将 sB 传递给 f()。

我有 boost 1.40 和 swig 1.3.40。

以下是 5 个文件的内容,它们将重现该问题 与:

python setup.py build_ext --inplace
python test.py

swig_shared_ptr.h

#ifndef INCLUDED_SWIG_SHARED_PTR_H
#define INCLUDED_SWIG_SHARED_PTR_H

#include <boost/shared_ptr.hpp>

class Base {};

class Derived : public Base {};

typedef boost::shared_ptr<Base> base_sptr;
typedef boost::shared_ptr<Derived> derived_sptr;

void do_something (base_sptr bs);

base_sptr make_base();
derived_sptr make_derived();

#endif

swig_shared_ptr.cc

#include <iostream>
#include "swig_shared_ptr.h"

void do_something (base_sptr bs)
{
  std::cout << "Doing something." << std::endl;
}

base_sptr make_base() { return base_sptr(new Base ()); };
derived_sptr make_derived() { return derived_sptr(new Derived ()); };

swig_shared_ptr.i

%module(docstring="
Example module showing problems I am having with SWIG, shared pointers
and inheritance.
") swig_shared_ptr

%{
#include "swig_shared_ptr.h"
%}

%include <swig_shared_ptr.h>
%include <boost_shared_ptr.i>
%template(base_sptr) boost::shared_ptr<Base>;
%template(derived_sptr) boost::shared_ptr<Derived>;

setup.py

"""
setup.py file for swig_shared_ptr
"""

from distutils.core import setup, Extension

swig_shared_ptr_module = Extension('_swig_shared_ptr',
                         include_dirs = ['/usr/include/boost'],
                         sources=['swig_shared_ptr.i', 'swig_shared_ptr.cc'],
                         )

setup (name = 'swig_shared_ptr',
       version = '0.1',
       author = "Ben",
       description = """Example showing problems I am having with SWIG, shared
                        pointers and inheritance.""",
       ext_modules = [swig_shared_ptr_module],
       py_modules = ["swig_shared_ptr"],
       )

test.py

import swig_shared_ptr as ssp

bs = ssp.make_base()
dr = ssp.make_derived()

# Works fine.
ssp.do_something(bs) 
# Fails with "TypeError: in method 'do_something', argument 1 of type 'base_sptr'"
ssp.do_something(dr) 

【问题讨论】:

    标签: c++ python boost swig shared-ptr


    【解决方案1】:

    以下更改似乎可以解决问题。

    swig_shared_ptr.i 中的两行:

    %template(base_sptr) boost::shared_ptr<Base>;
    %template(derived_sptr) boost::shared_ptr<Derived>;
    

    被移动到线的上方

    %include <swig_shared_ptr.h>
    

    然后被替换为(在 SWIG 1.3 中):

    SWIG_SHARED_PTR(Base, Base)
    SWIG_SHARED_PTR_DERIVED(Derived, Base, Derived)    
    

    或(在 SWIG 2.0 中)通过:

    %shared_ptr(Base)
    %shared_ptr(Derived)
    

    【讨论】:

      【解决方案2】:

      SWIG 对 boost::shared_ptr&lt;T&gt; 类一无所知。因此它不能告诉derived_sptr 可以“强制转换”(我相信,这是用一些疯狂的构造函数和模板元编程实现的)到derived_sptr。因为 SWIG 需要相当简单的类定义(或包含带有 %include 的简单文件),您将无法准确声明 shared_ptr 类,因为 Boost 难以置信编译器补偿和模板技巧。

      至于解决方案:分发共享指针是绝对必要的吗? SWIG 的 C++ 包装器基本上用作共享指针。 Boost 和 SWIG 很难一起工作。

      【讨论】:

      • 感谢您的回答。现在我知道为什么我遇到这么多麻烦了。
      • @gyroidben:如果这回答了您的问题,请单击我的答案旁边的复选标记。此外,如果将 Python 与 boost 结合使用非常重要,您可能还想看看 Boost::Python。
      • @gyroidben 在 Python 方面有 SWIG 的替代品。 Boost::Python 与 Py++ 结合创建了相同类型的自动跨语言集成,但可以处理 Boost 类型。
      猜你喜欢
      • 1970-01-01
      • 2012-10-19
      • 1970-01-01
      • 2020-05-03
      • 2018-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多