1.1 --- a/interface.c Thu Apr 23 23:12:19 2020 +0200
1.2 +++ b/interface.c Fri Apr 24 23:12:17 2020 +0200
1.3 @@ -51,6 +51,12 @@
1.4 write_includes_separator(iface->includes, fp);
1.5 write_includes(iface->includes, fp);
1.6
1.7 + /* Emit an include for memcpy usage in the compound interface conversion
1.8 + macro. */
1.9 +
1.10 + if (!cpp && !client)
1.11 + write_general_include("<string.h>", fp);
1.12 +
1.13 /* Generate interface abstractions. */
1.14
1.15 if (!cpp)
2.1 --- a/templates.h Thu Apr 23 23:12:19 2020 +0200
2.2 +++ b/templates.h Fri Apr 24 23:12:17 2020 +0200
2.3 @@ -122,8 +122,12 @@
2.4 #define compound_interfaces_prologue \
2.5 "#pragma once\n\n"
2.6
2.7 +/* Convert between object types by copying the reference type value into the
2.8 + temporarily allocated structure member which should appear first in the
2.9 + reference type. */
2.10 +
2.11 #define compound_interface_conversion \
2.12 -"\n#define convert_to_%s(_self) (&((%s) {.ref={.ptr=_self->ref.ptr}, .iface=_self->iface->to_%s}))\n"
2.13 +"\n#define convert_to_%s(_self) (memcpy(&((%s) {.iface=_self->iface->to_%s}).ref, &_self->ref, sizeof(ref_%s)))\n"
2.14
2.15 /* Dispatch functions. */
2.16
2.17 @@ -239,6 +243,9 @@
2.18 #define ref_type_definition_c \
2.19 "\ntypedef union { %s cap; void *ptr; } ref_%s;\n"
2.20
2.21 +/* Note that the conversion operation relies on the ref member appearing first.
2.22 + See: compound_interface_conversion */
2.23 +
2.24 #define object_type_definition_c \
2.25 "\ntypedef struct\n" \
2.26 "{\n" \