summaryrefslogtreecommitdiff
path: root/src/bin/eolian_mono/eolian/mono/struct_definition.hh
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2018-03-15 20:32:39 -0300
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2018-03-16 11:12:49 -0300
commit2705ea853108a64edc9264c8e5d4c79e55aea001 (patch)
tree7cbb95f4667ce4fa3d6c44a7b8e0e196a1ca757c /src/bin/eolian_mono/eolian/mono/struct_definition.hh
parent7c543d3c860c8c2d6979c55a0460d4ad3c983291 (diff)
csharp: Fix support for ptr(structs)
In general, ptr(struct) parameters behavior depends whether the parameter has the @owned modifier or not. If there is no @owned parameter (meaning no transfer of ownership happens) and it is a "complex" struct, with reference type fields (like strings), the struct is converted to the respective <Struct>Internal struct and passed with "ref" to the DllImport'd function. For @in parameters, after the function it returns, this intermediate struct is converted to the public struct type and assigned to the original parameter, updating it to the external world. When we have ownership transfers, the structure is copied to unmanaged memory and given to the callee. We can't send managed memory directly as the callee may try to free it. On the managed side, the original struct is left to be garbage collected normally.
Diffstat (limited to 'src/bin/eolian_mono/eolian/mono/struct_definition.hh')
-rw-r--r--src/bin/eolian_mono/eolian/mono/struct_definition.hh27
1 files changed, 23 insertions, 4 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/struct_definition.hh b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
index a0ff03315e..0b45da95b2 100644
--- a/src/bin/eolian_mono/eolian/mono/struct_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
@@ -94,10 +94,11 @@ struct struct_internal_definition_generator
94 { 94 {
95 if (!as_generator 95 if (!as_generator
96 ( 96 (
97 "///<summary>Internal wrapper for struct " << string << ".</summary>\n"
97 "[StructLayout(LayoutKind.Sequential)]\n" 98 "[StructLayout(LayoutKind.Sequential)]\n"
98 "internal struct " << string << "\n{\n" 99 "public struct " << string << "\n{\n"
99 ) 100 )
100 .generate(sink, binding_struct_internal_name(struct_), context)) 101 .generate(sink, std::make_tuple<>(binding_struct_name(struct_), binding_struct_internal_name(struct_)), context))
101 return false; 102 return false;
102 103
103 // iterate struct fields 104 // iterate struct fields
@@ -132,6 +133,24 @@ struct struct_internal_definition_generator
132 return false; 133 return false;
133 } 134 }
134 135
136 auto external_name = binding_struct_name(struct_);
137 auto internal_name = binding_struct_internal_name(struct_);
138
139 if(!as_generator(
140 scope_tab << "///<summary>Implicit conversion to the internal/marshalling representation.</summary>\n"
141 << scope_tab << "public static implicit operator " << string << "(" << string << " struct_)\n"
142 << scope_tab << "{\n"
143 << scope_tab << scope_tab << "return " << string << "_StructConvertion.ToExternal(struct_);\n"
144 << scope_tab << "}\n"
145 << scope_tab << "///<summary>Implicit conversion to the managed representation.</summary>\n"
146 << scope_tab << "public static implicit operator " << string << "(" << string << " struct_)\n"
147 << scope_tab << "{\n"
148 << scope_tab << scope_tab << "return " << string << "_StructConvertion.ToInternal(struct_);\n"
149 << scope_tab << "}\n"
150 ).generate(sink, std::make_tuple(external_name, internal_name, external_name,
151 internal_name, external_name, external_name), context))
152 return false;
153
135 if(!as_generator("}\n").generate(sink, attributes::unused, context)) return false; 154 if(!as_generator("}\n").generate(sink, attributes::unused, context)) return false;
136 155
137 return true; 156 return true;
@@ -172,7 +191,7 @@ struct to_internal_field_convert_generator
172 .generate(sink, std::make_tuple(field_name, field_name), context)) 191 .generate(sink, std::make_tuple(field_name, field_name), context))
173 return false; 192 return false;
174 } 193 }
175 else if (field.type.is_ptr && need_pointer_conversion(regular)) 194 else if (field.type.is_ptr && need_pointer_conversion(regular) && !need_struct_conversion(regular))
176 { 195 {
177 if (!as_generator( 196 if (!as_generator(
178 scope_tab << scope_tab << "_internal_struct." << string << " = eina.PrimitiveConversion.ManagedToPointerAlloc(_external_struct." << string << ");\n") 197 scope_tab << scope_tab << "_internal_struct." << string << " = eina.PrimitiveConversion.ManagedToPointerAlloc(_external_struct." << string << ");\n")
@@ -282,7 +301,7 @@ struct to_external_field_convert_generator
282 .generate(sink, std::make_tuple(field_name, field.type, field_name), context)) 301 .generate(sink, std::make_tuple(field_name, field.type, field_name), context))
283 return false; 302 return false;
284 } 303 }
285 else if (field.type.is_ptr && need_pointer_conversion(regular)) 304 else if (field.type.is_ptr && need_pointer_conversion(regular) && !need_struct_conversion(regular))
286 { 305 {
287 if (!as_generator( 306 if (!as_generator(
288 scope_tab << scope_tab << "_external_struct." << string << " = eina.PrimitiveConversion.PointerToManaged<" << type << ">(_internal_struct." << string << ");\n") 307 scope_tab << scope_tab << "_external_struct." << string << " = eina.PrimitiveConversion.PointerToManaged<" << type << ">(_internal_struct." << string << ");\n")