简体   繁体   English

麻烦析构函数,用boost.python中的指针调用python的对象

[英]Trouble destructor,call python's object with pointer in boost.python

when I call python's function with pointer as an argument in boost.python, there are some troubles in destructor. 当我在boost.python中使用指针作为参数调用python的函数时,析构函数中存在一些问题。 The following is a sample code 以下是示例代码

c++ C ++

#include <boost/python.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <string>
#include <iostream>
using namespace boost::python;

class A {
public:
    A() {
        std::cout<< "A start"<<std::endl;
    }
    ~A() {std::cout<< "A end" <<std::endl;}
}
class B {
public:
    B() { aa=new A; }
    ~B() { delete aa; }
    void run(object ct) {
        _obj=ct();              //creat a python object
        _obj.attr("fun1")(aa);  //call a function named "fun1" with a pointer arg
        _obj.attr("fun2")(aa);  //call a function named "fun2" with a pointer arg 
    }
    A *aa;
    object _obj;
}

BOOST_PYTHON_MODULE(ctopy)
{
    class_<A> ("A",init<>())
    ;
    class_<b> ("B",init<>())
    .def("run",&B::run)
    ;
}

python: 蟒蛇:

import ctopy
class tc:
    def fun1(self,tt):
        print "fun1"
    def fun2(self,tt):
        print "fun2"
bb=ctopy.D()
bb.run(tc)

this result: 这个结果:

A start
fun1
A end
fun2
A end
A end

note: 注意:

The "A end" has been printed three.I try it in "valgrind",there are some errors.I just want to run the destructor once.How to do? “A end”已打印三个。我在“valgrind”中尝试,有一些错误。我只想运行析构函数一次。怎么办?

To understand what's really happening, you're missing a copy-constructor: 为了理解真正发生的事情,你错过了一个拷贝构造函数:

B()
  A()
B::run()
  A(a)     <- copy construct A to pass by value
    fun1() <- arg passed by value
  ~A()     <- delete copy
  A(a)     <- copy construct A to pass by value
    fun2() <- arg passed by value
  ~A()     <- delete copy
~B()
  ~A()

In your example, aa is passed by value, that's where the copies come from. 在您的示例中, aa按值传递,即副本的来源。 It does not matter if aa is a pointer or not, boost will convert it to an object that is passed to your python methods. 无论aa是否为指针都无关紧要,boost会将其转换为传递给python方法的对象。

If you want to avoid additional copies of A you can pass aa by reference rather than by value : 如果您想避免使用A其他副本,则可以通过引用而不是按值传递aa

_obj.attr("fun1")(boost::ref(aa));
_obj.attr("fun2")(boost::ref(aa));

Which will result in: 这将导致:

B()
  A()    <- constructed once
B::run()
  fun1() <- arg passed by reference
  fun2() <- arg passed by reference
~B()
  ~A()   <- destroyed once

See Calling Python Functions and Methods for more info. 有关详细信息,请参阅调用Python函数和方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM