passing containers of char * (e.g. std::vector<char *>) does not work · Issue #2245 · pybind/pybind11 (original) (raw)

Issue description

pybind11 does not seem to correctly pass containers of char * to Python. I'm using the example of std::array<const char *, N>, but std::vectors have the same behavior. The char * received by C++ seems to be pointing to a random memory location. The memory is still within the process, as there are no segfaults (that I have seen, anyway).

Reproducible example code

This demo class has two separate constructors. One takes the type std::array<const char *, 2>, and the other takes the types const char *, const char*. The std::array version does the wrong thing, and the char *, when printed, just prints out garbage. The char *, char * version does the right thing, and prints the passed in string as expected.

I'm using pybind v2.5.0. I went through the docs on strings but didn't notice anything. Just guessing, but I would guess the problem might be shallow copies of pointers somewhere, since this only happens with containers. But I really have no clue.

This problem does not surface whenever std::string is used, which is another reason I think it may be related to shallow copies of pointers (since std::string will copy its data when copied).

#include #include <stdio.h>

#include <pybind11/pybind11.h> #include <pybind11/stl.h> namespace py = pybind11;

class Demo { public: Demo(std::array<const char *, 2> strs) { printf("Got %s %s\n", strs[0], strs[1]); } Demo(const char * str1, const char * str2) { printf("Got %s %s\n", str1, str2); } };

PYBIND11_MODULE(demo, m) { // the real deal here py::class_(m, "Demo") .def(py::init<std::array<const char *, 2>>()) .def(py::init<const char *, const char *>()) ; }

After building, the following Python code demonstrates the issue:

import demo

prints random garbage

demo.Demo(['string 1', 'string 2'])

prints the right thing

demo.Demo('string1', 'string2')