Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Problems of exposing const char * field in struct #2337

@zhanghb97

Description

@zhanghb97

Hi,

I found binding a struct contains const char * field may cause problems in my project. When I get a struct object from a function, the const char * field will be empty.
Here I use a prototype to show three situations:

// struct contains const char * field and other field.
struct A {
  const char *a1;
  int a2;
};
typedef struct A A;
A initA(const char *a1, int a2) {
  return A{a1, a2};
}

// struct contains const char * field and a nested struct.
struct B {
  const char * b;
  A a;
};
typedef struct B B;
B initB(const char *b, A a) {
  return B{b, a};
}

// struct only contains const char * field.
struct C {
  const char *c;
};
typedef struct C C;

C initC(const char *c) {
  return C{c};
}

And I use the following code to expose the fields in the struct:

PYBIND11_MODULE(test, m) {
  py::class_<A>(m, "A")
    .def_readwrite("a1", &A::a1)
    .def_readwrite("a2", &A::a2);
  m.def("initA", &initA);
  
  py::class_<B>(m, "B")
    .def_readwrite("b", &B::b)
    .def_readwrite("a", &B::a);
  m.def("initB", &initB);

  py::class_<C>(m, "C")
    .def_readwrite("c", &C::c);
  m.def("initC", &initC);
}

The results:

>>> import test
>>> test_a = test.initA("test_a", 10)
>>> test_b = test.initB("test_b", test_a)
>>> test_c = test.initC("test_c")
>>> print(test_a.a1)

>>> print(test_b.b)

>>> print(test_c.c)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf0 in position 0: invalid continuation byte

The expected output should be:

>>> print(test_a.a1)
test_a
>>> print(test_b.b)
test_b
>>> print(test_c.c)
test_c

But the actual output is empty and UnicodeDecodeError. I tried def_readonly and def_readwrite to expose the const char * field, but they cause the same problem. I'm not sure is this because the lifetime of const char * has already ended when I want to print it? And why the string caused the UnicodeDecodeError? Am I missing something important, how could I solve these problems without touching the source code?

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions