I am attempting to create python bindings using pybind11(v2.2.2+) and cannot figure out how to invoke a C function that has a single std::initializer_list argument.
void list_ints(std::initializer_list<int>)
And the pybind11 binding is:
m.def("list_ints", &list_ints)
From python, I'm trying to invoke like this:
list_ints(1, 2, 3)
Here is the sample C code compiled using llvm on MacOS with -std=C++14
:
#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);
}
The python code contains a description of the results:
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)
This test code demonstrates that binding with arguments defined as const int &a, const int &b
does match and invoke the list_ints function but something is clearly not right as a seg fault occurs upon accessing the arguments.
$ 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
Is there a way to bind and invoke void list_ints(std::initializer_list<int>)
from Python?