MSVC workaround for "C linkage function cannot return C++ class"
MSVC fails to compile code like the following unless there is an
explicit instantiation of the class template:
template <typename T>
class slice {};
//template class slice<int>;
extern "C" slice<int> repro() { return {}; }
Error:
<source>(6): error C2526: 'repro': C linkage function cannot return C++ class 'slice<int>'
<source>(6): note: see declaration of 'slice<int>'
<source>(6): error C2562: 'repro': 'void' function returning a value
<source>(6): note: see declaration of 'repro'
Compiler returned: 2
diff --git a/gen/src/write.rs b/gen/src/write.rs
index 73a4b8c..3e79548 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -119,6 +119,22 @@
}
}
+ out.set_namespace(Default::default());
+
+ out.next_section();
+ for ty in out.types {
+ // MSVC workaround for "C linkage function cannot return C++ class"
+ // error. Apparently the compiler fails to perform implicit
+ // instantiations as part of an extern declaration. Instead we
+ // instantiate explicitly.
+ // See https://stackoverflow.com/a/57429504/6086311.
+ if let Type::SliceRef(_) = ty {
+ write!(out, "template struct ");
+ write_type(out, ty);
+ writeln!(out, ";");
+ }
+ }
+
out.next_section();
for api in apis {
if let Api::TypeAlias(ety) = api {