boost python make_构造函数和保管人与沃德

2024-06-16 15:08:31 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有以下两个C++类(我不能修改):

struct A
{
    // stuff
};

struct B
{
    // B will internally hold a reference to a
    B(A& a, some_cpp_only_type arg);
};

我试图包装B类,并在Python接口中隐藏some_cpp_only_type参数(没有这个参数,B没有替代的构造函数)。在

我现在有以下包装器代码:

^{pr2}$

现在这是可行的,因为我在Python中保存了对包装的A对象的引用。但是,我真的希望至少在B的实例被破坏之前保持这个状态。我尝试向with_custodian_and_ward_postcall添加一个with_custodian_and_ward_postcall调用策略,但是我得到了几页毫无意义的编译器错误(甚至来自Clang)。以下是修改后的无效代码:

using namespace boost::python;

boost::shared_ptr<B> make_B(A& a)
{
    return boost::make_shared<B>(a, get_cpp_only_instance());
}

BOOST_PYTHON_MODULE(my_module)
{
    class_<B, boost::noncopyable>("B", no_init)
      .def("__init__", make_constructor(&make_B, with_custodian_and_ward_postcall<0,1>()));
}

如何在使用make_constructor时正确指定调用策略?在

使用make_函数的替代尝试

我尝试使用make_function包装的解决方案Tanner Sansbury posted here,但这次即使编译成功,我还是从Python内部得到了一个ValueError

No to_python (by-value) converter found for C++ type: A

作为参考,下面是我尝试过的使用make_function的代码(无论有没有托管人/病房呼叫策略,我都会得到相同的错误):

using namespace boost::python;

boost::shared_ptr<B> make_B(A& a)
{
    return boost::make_shared<B>(a, get_cpp_only_instance());
}

void inter_make_B(object self, A& a)
{
    auto constructor = make_constructor(&make_B);
    constructor(self, a);
}

BOOST_PYTHON_MODULE(my_module)
{
    class_<B, boost::noncopyable>("B", no_init)
      .def("__init__", make_function(&inter_make_B, with_custodian_and_ward<1,2>()));
}

如何正确地为B编写包装器,它可以正确地管理内存而不修改B类?在


Tags: and代码onlymakeinittypewith策略