fsvb and foreign-typedefs with aggregate types

Madhu enometh at meer.net
Fri Feb 14 10:41:16 UTC 2020


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)



More information about the cffi-devel mailing list