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)