2

在我的 C++ 代码中,我有一个 Foo 类,其中有许多将 Bar 类型变量作为参数的方法:

class Foo {
public:
  void do_this(Bar b);
  void do_that(Bar b);
  /* ... */
};

Bar 有许多构造函数,它们从许多常见类型(例如 int、std::string、float 等)创建新对象:

class Bar {
public:
  Bar(int i);
  Bar(float f);
  Bar(std::string s);
  /* ... */
};

我用 Boost::Python 包装了它,现在我可以直接使用 Python 文字调用我的 Foo 方法,因为它们被隐式转换为 Bar 对象。

f = Foo()
f.do_this(5)
f.do_that("hello")

现在,我还希望能够使用其他 Python 类型,例如元组,如下所示:

f.do_that((1,2,3))

但我不想触碰最初的 Bar 定义,也不想用 Boost::Python 的东西污染我的 C++ 库。我想在我的绑定代码中编写一个包装函数,但我不明白这是否可行,以及这样做的正确方法是什么。

换句话说:我可以注册一个工厂函数以用作 Python 中的自动转换吗?

4

6 回答 6

2

包装器代码附近的子类 Bar 并为您的子类提供一个接受 bp::object (或更具体的 python 类型)的 ctor

struct Bar_wrapper:Bar,bp::wrapper<Bar>
{
    Bar_wrapper(bp::object arg)
    {
        //code to build a Bar_wrapper Here
    }
}

然后将 Bar_wrapper 导出到 python 而不是 Bar,并将其称为 Bar 作为 python 名称:

class<Bar_wrapper>("Bar")
    ...
    .def(init<bp::object>())
    ...
于 2010-11-09T19:46:57.880 回答
1

在您的标头中添加一个新的构造函数template <typename T> Bar(T) 并实现为template <> Bar::Bar(Tupple) {}

于 2011-09-13T12:07:38.920 回答
0

创建某种类型的 TupleCollector 并重写“operator ,(int)”,以便您可以编写

f.do_that((TuppleCollector(), 1, 2, 3))

最后在 TupleCollector 和预期目标之间创建转换

于 2009-08-10T10:03:26.313 回答
0

您可以注册 from-python 转换器,它将Bar从任意对象构造实例。请参见此处和我自己的示例(将(Vector3,Quaternion)元组或 7*double-tuple 转换为 3d 转换Se3here

请注意,该逻辑有两个步骤,首先您确定对象是否可转换(convertible在您的情况下,您检查它是否是一个序列,并且具有正确的元素数量),然后construct调用该方法,该方法实际上返回实例,使用作为参数传递的指针进行分配。

然后必须在 中注册转换器BOOST_PYTHON_MODULE。由于转换器注册表是全局的,一旦注册,它将在任何地方自动使用。所有类型的函数参数Barorconst Bar&都应该处理得很好(Bar&我也不确定)。

于 2011-09-13T14:12:13.910 回答
0

您可以创建一个静态工厂方法,然后将其公开为该类的 Python 构造函数之一。只需制作一个可以接受任何 Python 对象的转换器,您就可以随心所欲地做任何事情。

using namespace boost::python;

Bar CreateBar(object obj)
{
    // Do your thing here

    return Bar;
}

// ..................

class_<Bar>("Bar")
    // .....................
    .def("__init__", make_constructor(&CreateBar))
    //.............
    ;
于 2011-09-13T13:38:43.080 回答
-1

您可以导出函数 do_that,它采用 boost::python::object 参数,检查参数是否是 python 元组,提取数据并将其传递给对象。

于 2009-12-11T11:21:35.227 回答