diff --git a/src/cffi.cpp b/src/cffi.cpp index 49795d32..8135df43 100644 --- a/src/cffi.cpp +++ b/src/cffi.cpp @@ -125,18 +125,19 @@ namespace pkpy{ void C99Struct::_register(VM* vm, PyObject* mod, PyObject* type){ vm->bind_constructor<-1>(type, [](VM* vm, ArgsView args){ + Type cls = PK_OBJ_GET(Type, args[0]); if(args.size() == 1+1){ if(is_int(args[1])){ int size = _CAST(int, args[1]); - return VAR_T(C99Struct, size); + return vm->heap.gcnew(cls, size); } if(is_non_tagged_type(args[1], vm->tp_str)){ const Str& s = _CAST(Str&, args[1]); - return VAR_T(C99Struct, (void*)s.data, s.size); + return vm->heap.gcnew(cls, (void*)s.data, s.size); } if(is_non_tagged_type(args[1], vm->tp_bytes)){ const Bytes& b = _CAST(Bytes&, args[1]); - return VAR_T(C99Struct, (void*)b.data(), b.size()); + return vm->heap.gcnew(cls, (void*)b.data(), b.size()); } vm->TypeError("expected int, str or bytes"); return vm->None; @@ -144,7 +145,7 @@ namespace pkpy{ if(args.size() == 1+2){ void* p = CAST(void*, args[1]); int size = CAST(int, args[2]); - return VAR_T(C99Struct, p, size); + return vm->heap.gcnew(cls, p, size); } vm->TypeError("expected 1 or 2 arguments"); return vm->None; diff --git a/tests/80_c.py b/tests/80_c.py index 35e6d464..6abfdf4e 100644 --- a/tests/80_c.py +++ b/tests/80_c.py @@ -32,4 +32,27 @@ for i in range(10): assert array2.offset(i).read_char() == 0 c.free(array) -c.free(array2) \ No newline at end of file +c.free(array2) + +class Vec2(c.struct): + def __new__(cls, x: float, y: float): + obj = c.struct.__new__(cls, 8) + obj.write_float(x, 0) + obj.write_float(y, 4) + return obj + + @property + def x(self) -> float: + return self.read_float(0) + + @property + def y(self) -> float: + return self.read_float(4) + + def __repr__(self) -> str: + return f"Vec2({self.x}, {self.y})" + +a = Vec2(1, 2) +assert isinstance(a, c.struct) +assert type(a) is Vec2 +assert repr(a) == "Vec2(1.0, 2.0)"