使用pybind11将函数与std :: initializer_list参数绑定

问题描述 投票:0回答:1

我试图使用pybind11(v2.2.2 +)创建python绑定,并且无法弄清楚如何调用具有单个std :: initializer_list参数的C函数。

void list_ints(std::initializer_list<int>)

而pybind11绑定是:

m.def("list_ints", &list_ints)

从python,我试图像这样调用:

list_ints(1, 2, 3)

以下是使用qzxswpoi在MacOS上使用llvm编译的示例C代码:

-std=C++14

python代码包含结果的描述:

#include <iostream>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

using namespace std;
namespace py = pybind11;

void list_ints(const std::initializer_list<int> &il) {
    std::cout << "Got to list_ints ..." << std::endl;
    for (const auto &elem : il)
        std::cout << to_string(elem) << " ";
    std::cout << std::endl;
};

PYBIND11_MODULE(initializer, m) {
    m.def("list_ints", &list_ints);
    m.def("list_ints", (void (*) (const std::initializer_list<int>&)) &list_ints);
    # This is the only binding that seems to work .. sort of.
    m.def("list_ints", (void (*) (const int &a, const int &b)) &list_ints);
}

此测试代码演示了与定义为from initializer import list_ints try: # Fails with: TypeError: Incompatible function arguments print("Calling list_ints(1, 2, 3)") list_ints(1, 2, 3) except TypeError as err: print(err) # Call succeeds but function Seg Faults! print("Calling list_ints(1, 2)") list_ints(1,2) 的参数的绑定确实匹配并调用了list_ints函数,但由于在访问参数时发生了seg错误,因此显然不正确。

const int &a, const int &b

有没有办法从Python绑定和调用$ python initializer.py Calling list_ints(1, 2, 3) list_ints(): incompatible function arguments. The following argument types are supported: 1. (arg0: std::initializer_list<int>) -> None 2. (arg0: std::initializer_list<int>) -> None 3. (arg0: int, arg1: int) -> None Invoked with: 1, 2, 3 Did you forget to `#include <pybind11/stl.h>`? Or <pybind11/complex.h>, <pybind11/functional.h>, <pybind11/chrono.h>, etc. Some automatic conversions are optional and require extra headers to be included when compiling your pybind11 module. Calling list_ints(1, 2) Got to list_ints ... Segmentation fault: 11

pybind11
1个回答
0
投票

我在pybind11 repo上收到了[email protected]的回复:

它不受支持,我相信,不可能支持:初始化列表是故意不透明的类型,只能由C ++编译器构建,而不是由C ++代码构建 - 这意味着它对我们来说是不可能的接受。

有关更多详细信息,请参阅void list_ints(std::initializer_list<int>)的答案。

至于你的绑定代码,你基本上是将你的函数转换为一个采用不同类型的函数。 Pybind构造一个C++11 is it possible to construct an std::initializer_list?,然后传递它作为函数参数,但函数认为它得到一个reintepret_cast - 然后坏事发生。它基本上是为std::vector<int>做论证,其中std::initializer_listauto &il = reintepret_cast<std::initializer_list<int> &>(v)

© www.soinside.com 2019 - 2024. All rights reserved.