Consider the following definitions
(defcstruct record1 (a :int) (b :int)) (defctype record1-type (:struct record1)) (defcstruct record2a (r (:struct record1)) (c :int)) (defcstruct record2b (r record1-type) (c :int))
record2a_type and record2b_type have identical representations. However when translating structs using libffi-fsvb record2b_type will put a pointer in the r field rather than translating the typedef:
struct record2a foo_a() { return (struct record2a) { .r = { .a = 1, .b = 2 }, .c = 2 }; }
struct record2a foo_b() { return (struct record2a) { .r = { .a = 1, .b = 2 }, .c = 2 }; }
(setq $a (cffi:foreign-funcall "foo_a" (:struct record2a))) ;; => (R (B 2 A 1) C 2) (setq $b (cffi:foreign-funcall "foo_b" (:struct record2b))) ;; => (R #<foreign :VOID 0x1566e70> C 2)
The pointer in the r field is useless, because of its extent.
The immediate fix for this is to define (either in structures or early-types)
(defmethod translate-from-foreign (value (type foreign-typedef)) (translate-from-foreign value (follow-typedefs)))
so foreign-typedefs always resolve to a structure
But I am not sure. Does this have other ramifications: there seems to be confusion over how typedefs are resolved (and I do not understand code for the bare structs and enhanced-typedefs - perhaps I am expected to go about this problem in some other way? Am I expected to define methods on translate-from-foreign-memory? or should CFFI always translate nested aggregates to lisp lists)