Skip to content

Invoking a C function with std::initializer_list argument #1302

Closed
@bbarcklay

Description

@bbarcklay

I cannot figure out how to invoke a C function with an std::initializer_list argument from Python. I posted this question first on Stackoverflow then in the Gitter chat room. I also looked around for a relevant test case and could not find one. Perhaps this is not supported? The C function is:

#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) {
    // This does not match anything
    m.def("list_ints", &list_ints);
    // This matches a list argument and invokes the function, then BOOM.
    m.def("list_ints", (void (*) (const std::vector<int>&)) &list_ints);
}

The python code to invoke this function is:

from initializer import list_ints
l = [1,2]
# Call succeeds but function Seg Faults!
list_ints(l)
print(l)

The function only succeeds with the addition of the second m.def() above. Using only m.def("list_ints", &list_ints) results in a TypeError: list_ints(): incompatible function arguments whether I'm passing *args or a single list. With the second binding in place, the output is:

Got to list_ints ...
1 2 0 -1073741824 0 0 259188368 ...

and then BOOM. It iterates off the end of the initializer list. I'm running on MacOS/llvm, --std=c++14, Python 3.4. I can call this same function in C with list_ints({1,2,3,4,5}) and it works as expected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions