Structures with typedef
integerfn opened this issue · comments
Hi! Thanks for the tremendous work. I've been looking for something like this for a long time.
I'm just getting started and trying to get the hang of it. The first issue I encountered which I have not been able to solve is related to structures defined with typedef. I have a mixed C/C++ codebase and we have several structs typedef'd like this:
typedef struct {
int x;
} MyStruct ;
From what I have seen, litgen
ignores these type definitions. Also tried using
and got a similar results. Is there a configuration I need to enable to have type aliases included? I'm working with cppimport, but as far as I can tell the binding code is already missing for these types so I don't think that makes a difference.
Here's a simple example:
typedef struct {
int x;
int y;
} Vector2D;
int VectorNorm2( Vector2D v )
{
return v.x * v.x + v.y * v.y;
}
This produces something that is missing the type definition
# stub
def vector_norm2(v: Vector2D) -> int:
pass
// pydef
m.def("vector_norm2",
VectorNorm2, py::arg("v"));
Any help is appreciated
Thanks!
Hello, thanks for the compliment, litgen was indeed a lot of work!
Concerning your issue I would think that you should use the code pre-processing utilities, and thus write a small Python function that transforms those structs into standard C++ structs.
I did ask ChatGPT and he had a proposition which I did not test:
https://chat.openai.com/share/e0cea5b6-7cb3-4e0e-9fd3-d982c915911c
Hi again, thanks for the super fast answer. Your suggested workaround worked great for my case, at least for the simple example I was playing around with, I'll have to try it with the full codebase at some point and see if something else breaks.
I did find something else that looks like a bug, which is related to this. See this simple type alias:
struct Vector2D {
int x;
int y;
};
using VectorAlias = Vector2D;
int VectorNorm2( VectorAlias v )
{
return v.x * v.x + v.y * v.y;
}
Now the produced pybind code is alright:
auto pyClassVector2D =
py::class_<Vector2D>
(m, "Vector2D", "")
.def(py::init<>([](
int x = int(), int y = int())
{
auto r = std::make_unique<Vector2D>();
r->x = x;
r->y = y;
return r;
})
, py::arg("x") = int(), py::arg("y") = int()
)
.def_readwrite("x", &Vector2D::x, "")
.def_readwrite("y", &Vector2D::y, "")
;
m.def("vector_norm2",
VectorNorm2, py::arg("v"));
However, the stub isn't:
class Vector2D:
x: int
y: int
def __init__(self, x: int = int(), y: int = int()) -> None:
"""Auto-generated default constructor with named params"""
pass
def vector_norm2(v: VectorAlias) -> int:
pass
As VectorAlias
hasn't been defined, the autocomplete doesn't work in PyCharm. Is this intended?
Thanks!
In this case, manually add this:
VectorAlias: TypeAlias = Vector2D
In the stub file (before the autogenerated part)