在Python中从SWIG实例化共享的\u ptr对象

在Python中从SWIG实例化共享的\u ptr对象,python,c++,swig,Python,C++,Swig,我有一个基类和一些派生类 这可以从类似Python的应用程序中使用 import test s = test.Square() a = test.Add1(s) print(a.eval(2.0)) 什么是断层: 为什么??test.Square()未分配给变量,因此在分配给a后不再存在,obj指向无效存储 为了避免这种行为,建议使用std::shared\u ptr而不是基类&,即 class Add1: public BaseClass { public: Add1(std::s

我有一个
基类和一些派生类

这可以从类似Python的应用程序中使用

import test
s = test.Square()
a = test.Add1(s)
print(a.eval(2.0))
什么是断层:

为什么??
test.Square()
未分配给变量,因此在分配给
a
后不再存在,
obj
指向无效存储

为了避免这种行为,建议使用
std::shared\u ptr
而不是
基类&
,即

class Add1: public BaseClass
{
  public:
  Add1(std::shared_ptr<BaseClass> & obj): obj_(obj) {}

  double eval(double x) const {return obj_->eval(x) + 1.0;}

  private:
  std::shared_ptr<BaseClass> obj_;
};
class Add1:公共基类
{
公众:
Add1(std::shared_ptr&obj):obj_j(obj){}
double eval(double x)const{return obj_uj->eval(x)+1.0;}
私人:
std::共享对象;
};
但是,这个精确的代码无法与

TypeError: in method 'new_Add1', argument 1 of type 'std::shared_ptr< BaseClass > &'
TypeError:在方法“new\u Add1”中,参数1的类型为“std::shared\u ptr&”
同样有道理:
test.Square()
不会返回
std::shared_ptr
而只是一个
Square
aka
BaseClass
实例

有没有可能让
test.Square()
返回一个共享指针
std::shared\u ptr

SWIG的性能非常好。这一切都非常透明,因此您需要对.i文件进行的更改如下:

%module test

%{
#define SWIG_FILE_WITH_INIT
#include "test.h"
%}

%include <std_shared_ptr.i>

%shared_ptr(Square);
%shared_ptr(BaseClass);
%shared_ptr(Add1); // Not actually needed to make your demo work, but a good idea still

%include "test.h"
对于非智能指针参数,它也应该“正常工作”,但请注意,现在该层次结构中所有Python创建的实例都将是“智能”的


(如果您感兴趣,我也介绍了和之前的内容)。

可以这样做,但这不是您想要的-您想要
test.Square()
返回类型为
std::shared\u ptr
的共享指针,然后让
test.Add1()
隐式转换它们,因为这意味着您可以在Python中使用
Square
特定的成员。我会制定一个计划,这也是我的初衷。在案文中加以澄清。谢谢
class Add1: public BaseClass
{
  public:
  Add1(std::shared_ptr<BaseClass> & obj): obj_(obj) {}

  double eval(double x) const {return obj_->eval(x) + 1.0;}

  private:
  std::shared_ptr<BaseClass> obj_;
};
TypeError: in method 'new_Add1', argument 1 of type 'std::shared_ptr< BaseClass > &'
%module test

%{
#define SWIG_FILE_WITH_INIT
#include "test.h"
%}

%include <std_shared_ptr.i>

%shared_ptr(Square);
%shared_ptr(BaseClass);
%shared_ptr(Add1); // Not actually needed to make your demo work, but a good idea still

%include "test.h"
import test
sq=test.Square()
test.Add1(sq) # implicitly converted to shared_ptr<BaseClass> here
sq.onlySquare()
print sq
# <test.Square; proxy of <Swig Object of type 'std::shared_ptr< Square > *' at 0xf7424950> >