如何 Package 自定义C++类型以用于pybind11,如果它们可以用文字初始化?

puruo6ea  于 2023-04-08  发布在  其他
关注(0)|答案(1)|浏览(97)

我正在用pybind 11将Python解释器嵌入到我的C代码中。
我想从Python代码中调用C
函数,所以我必须先 Package 它们,不幸的是,它们接受各种自定义类型作为参数。
void func_i_like_to_use(CustomeType a, AnotherCustomeType b);
通常情况下,我现在也会开始 Package 它们,但它们是一个很深的继承层次结构,中间混合了许多模板类和typedef名称。换句话说:复制整棵树会真实的痛苦。

//... more BaseTemplate hierarchy

template <T>
class CustomTemplate<T>: public BaseTemplate<T>;

typedef CustomTemplate<float> CustomType;

幸运的是,几乎所有的参数都可以用纯文字或枚举值初始化。主要是因为它们有构造函数,可以将POD类型更深地传递到类树中,或者因为它们有类型转换功能。
function_i_like_to_use(5.7, "My string literal");
现在从Python开始,使用这些字面形式就足够了。有没有一种方法可以用替代类型来 Package 这些函数,这些替代类型在调用函数时可以工作,但与声明的实际函数参数类型不匹配?

PYBIND_EMBEDDED_MODULE(example, m)
{

// this compiles, but can't be called with literals
m.def("func_i_like_to_use", &func_i_like_to_use, "Want to call from Python",
      pybind11::arg("a"), pybind11::arg("b"))
}

// this doesn't compile, as it doesn't match the function declaration
m.def("func_i_like_to_use", static_cast<void (*)(float, std::string)>(&func_i_like_to_use), "Want to call from Python",
      pybind11::arg("a"), pybind11::arg("b"))
}

pybind11::exec("import example"
        "example.func_i_like_to_use(5.8, 'hello world')");

我可以用POD参数在C++中再次 Package 函数,但是有时候,即使用字面量调用函数可以工作,用POD类型调用它们也不行,所以我不能将 Package 的参数传递给原始函数。
我可以用pybind 11 Package CustomType的第一个顺序,但是 Package 实际的构造函数不足以允许使用文字调用。也许我可以在这里插入“虚拟”构造函数,仅供Python使用?这将如何与pybind 11一起工作?
更新:固定了pybind 11::arg()的用法;修改的实验函数bind with static_cast)

lymnna71

lymnna711#

最简单的方法是使用lambda并 Package 调用:

m.def(
    "func_i_like_to_use",
    [](float a, std::string const& s) {
        return func_i_like_to_use(a, s);
    },
    "Want to call from Python");

相关问题