diff --git a/src/bin/eolian_mono/eolian/mono/helpers.hh b/src/bin/eolian_mono/eolian/mono/helpers.hh index 28b54a5aef..7d013bd6f5 100644 --- a/src/bin/eolian_mono/eolian/mono/helpers.hh +++ b/src/bin/eolian_mono/eolian/mono/helpers.hh @@ -33,7 +33,6 @@ inline std::string struct_full_name(attributes::struct_def const& struct_) inline bool is_struct_blacklisted(std::string const& full_name) { return full_name == "Efl.Event.Description" - // || full_name == "Eina.File" || full_name == "Eina.Binbuf" || full_name == "Eina.Slice" || full_name == "Eina.Rw_Slice"; @@ -54,6 +53,30 @@ inline bool need_struct_conversion(attributes::regular_type_def const* regular) return regular && regular->is_struct() && !is_struct_blacklisted(*regular); } +inline bool need_pointer_conversion(attributes::regular_type_def const* regular) +{ + if (!regular) + return false; + + if (regular->is_enum() + || (regular->is_struct() && type_full_name(*regular) != "Eina.Binbuf") + ) + return true; + + std::set const types { + "bool", "char" + , "byte" , "short" , "int" , "long" , "llong" , "int8" , "int16" , "int32" , "int64" , "ssize" + , "ubyte", "ushort", "uint", "ulong", "ullong", "uint8", "uint16", "uint32", "uint64", "size" + , "ptrdiff" + , "float", "double" + }; + if (types.find(regular->base_type) != types.end()) + return true; + + return false; +} + + } #endif diff --git a/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh b/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh index 7950b31213..89efc7f3e2 100644 --- a/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh +++ b/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh @@ -149,7 +149,7 @@ struct marshall_type_visitor_generate }} }; - if (regular.is_struct() && !is_struct_blacklisted(regular)) + if (!is_ptr && regular.is_struct() && !is_struct_blacklisted(regular)) { return as_generator(*(lower_case[string] << ".") << string << "_StructInternal") .generate(sink, std::make_tuple(eolian_mono::escape_namespace(regular.namespaces), regular.base_type), *context); @@ -169,14 +169,21 @@ struct marshall_type_visitor_generate { return *b; } + else if (is_ptr && need_pointer_conversion(®ular)) + { + regular_type_def r = regular; + r.base_type = " System.IntPtr"; + r.namespaces.clear(); + return visitor_generate{sink, context, c_type, is_out, is_return, is_ptr}(r); + } else { - return visitor_generate{sink, context, c_type, is_out, is_return}(regular); + return visitor_generate{sink, context, c_type, is_out, is_return, is_ptr}(regular); } } bool operator()(attributes::klass_name klass_name) const { - return visitor_generate{sink, context, c_type, is_out, is_return}(klass_name); + return visitor_generate{sink, context, c_type, is_out, is_return, is_ptr}(klass_name); // return as_generator(" System.IntPtr").generate(sink, attributes::unused, *context); } bool operator()(attributes::complex_type_def const& complex) const @@ -259,7 +266,7 @@ struct marshall_type_visitor_generate } //return default_match(complex); - return visitor_generate{sink, context, c_type, is_out, is_return}(complex); + return visitor_generate{sink, context, c_type, is_out, is_return, is_ptr}(complex); // return as_generator(" System.IntPtr").generate(sink, attributes::unused, *context); } }; diff --git a/src/bin/eolian_mono/eolian/mono/parameter.hh b/src/bin/eolian_mono/eolian/mono/parameter.hh index 0e3fa326d5..834ca1248d 100644 --- a/src/bin/eolian_mono/eolian/mono/parameter.hh +++ b/src/bin/eolian_mono/eolian/mono/parameter.hh @@ -269,6 +269,9 @@ inline bool param_should_use_out_var(attributes::parameter_def const& param, boo if (need_struct_conversion(regular)) return true; + if (param.type.is_ptr && need_pointer_conversion(regular)) + return true; + return false; } @@ -314,6 +317,9 @@ inline bool param_should_use_in_var(attributes::parameter_def const& param, bool if (need_struct_conversion(regular)) return true; + if (param.type.is_ptr && need_pointer_conversion(regular)) + return true; + return false; } @@ -501,7 +507,13 @@ struct native_convert_in_variable_generator return true; auto regular = efl::eina::get(¶m.type.original_type); - if (need_struct_conversion(regular)) + if (param.type.is_ptr && need_pointer_conversion(regular)) + { + return as_generator( + "var " << string << " = eina.PrimitiveConversion.PointerToManaged<" << type << ">(" << escape_keyword(param.param_name) << ");\n" + ).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context); + } + else if (need_struct_conversion(regular)) { return as_generator( "var " << string << " = " << type << "_StructConvertion.ToExternal(" << escape_keyword(param.param_name) << ");\n" @@ -563,7 +575,13 @@ struct convert_in_variable_generator return true; auto regular = efl::eina::get(¶m.type.original_type); - if (need_struct_conversion(regular)) + if (param.type.is_ptr && need_pointer_conversion(regular)) + { + return as_generator( + "var " << string << " = eina.PrimitiveConversion.ManagedToPointerAlloc(" << escape_keyword(param.param_name) << ");\n" + ).generate(sink, in_variable_name(param.param_name), context); + } + else if (need_struct_conversion(regular)) { return as_generator( "var " << string << " = " << type << "_StructConvertion.ToInternal(" << escape_keyword(param.param_name) << ");\n" @@ -651,7 +669,13 @@ struct convert_out_variable_generator return true; auto regular = efl::eina::get(¶m.type.original_type); - if (need_struct_conversion(regular)) + if (param.type.is_ptr && need_pointer_conversion(regular)) + { + return as_generator( + "System.IntPtr " << string << " = System.IntPtr.Zero;\n" + ).generate(sink, out_variable_name(param.param_name), context); + } + else if (need_struct_conversion(regular)) { return as_generator( "var " << string << " = new " << marshall_type << "();\n" @@ -718,7 +742,13 @@ struct native_convert_out_variable_generator return true; auto regular = efl::eina::get(¶m.type.original_type); - if (need_struct_conversion(regular) + if (param.type.is_ptr && need_pointer_conversion(regular)) + { + return as_generator( + type << " " << string << " = default(" << type << ");\n" + ).generate(sink, std::make_tuple(param, out_variable_name(param.param_name), param), context); + } + else if (need_struct_conversion(regular) || param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT) || param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT)) { @@ -798,7 +828,13 @@ struct convert_out_assign_generator return true; auto regular = efl::eina::get(¶m.type.original_type); - if (need_struct_conversion(regular)) + if (param.type.is_ptr && need_pointer_conversion(regular)) + { + return as_generator( + string << " = eina.PrimitiveConversion.PointerToManaged<" << type << ">(" << out_variable_name(param.param_name) << ");\n" + ).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type), context); + } + else if (need_struct_conversion(regular)) { return as_generator( string << " = " << type << "_StructConvertion.ToExternal(" << out_variable_name(param.param_name) << ");\n" @@ -894,7 +930,13 @@ struct convert_return_generator bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const { auto regular = efl::eina::get(&ret_type.original_type); - if (need_struct_conversion(regular)) + if (ret_type.is_ptr && need_pointer_conversion(regular)) + { + return as_generator( + "return eina.PrimitiveConversion.PointerToManaged<" << type << ">(_ret_var);\n" + ).generate(sink, ret_type, context); + } + else if (need_struct_conversion(regular)) { return as_generator( "return " << type << "_StructConvertion.ToExternal(_ret_var);\n" @@ -956,7 +998,13 @@ struct native_convert_out_assign_generator return true; auto regular = efl::eina::get(¶m.type.original_type); - if (need_struct_conversion(regular)) + if (param.type.is_ptr && need_pointer_conversion(regular)) + { + return as_generator( + string << " = eina.PrimitiveConversion.ManagedToPointerAlloc(" << string << ");\n" + ).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context); + } + else if (need_struct_conversion(regular)) { return as_generator( string << " = " << type << "_StructConvertion.ToInternal(" << string << ");\n" @@ -1083,7 +1131,13 @@ struct native_convert_return_generator bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const { auto regular = efl::eina::get(&ret_type.original_type); - if (need_struct_conversion(regular)) + if (ret_type.is_ptr && need_pointer_conversion(regular)) + { + return as_generator( + "return eina.PrimitiveConversion.ManagedToPointerAlloc(_ret_var);\n" + ).generate(sink, attributes::unused, context); + } + else if (need_struct_conversion(regular)) { return as_generator( "return " << type << "_StructConvertion.ToInternal(_ret_var);\n" diff --git a/src/bin/eolian_mono/eolian/mono/struct_definition.hh b/src/bin/eolian_mono/eolian/mono/struct_definition.hh index 62992357f2..85cc14cc0d 100644 --- a/src/bin/eolian_mono/eolian/mono/struct_definition.hh +++ b/src/bin/eolian_mono/eolian/mono/struct_definition.hh @@ -156,6 +156,13 @@ struct to_internal_field_convert_generator .generate(sink, std::make_tuple(field_name, field_name), context)) return false; } + else if (field.type.is_ptr && need_pointer_conversion(regular)) + { + if (!as_generator( + scope_tab << scope_tab << "_internal_struct." << string << " = eina.PrimitiveConversion.ManagedToPointerAlloc(_external_struct." << string << ");\n") + .generate(sink, std::make_tuple(field_name, field_name), context)) + return false; + } else if (need_struct_conversion(regular)) { if (!as_generator( @@ -259,6 +266,13 @@ struct to_external_field_convert_generator .generate(sink, std::make_tuple(field_name, field.type, field_name), context)) return false; } + else if (field.type.is_ptr && need_pointer_conversion(regular)) + { + if (!as_generator( + scope_tab << scope_tab << "_external_struct." << string << " = eina.PrimitiveConversion.PointerToManaged<" << type << ">(_internal_struct." << string << ");\n") + .generate(sink, std::make_tuple(field_name, field.type, field_name), context)) + return false; + } else if (need_struct_conversion(regular)) { if (!as_generator( diff --git a/src/bin/eolian_mono/eolian/mono/type.hh b/src/bin/eolian_mono/eolian/mono/type.hh index b0e14516ce..b968d9e0bc 100644 --- a/src/bin/eolian_mono/eolian/mono/type.hh +++ b/src/bin/eolian_mono/eolian/mono/type.hh @@ -20,13 +20,13 @@ struct type_generator template bool generate(OutputIterator sink, attributes::type_def const& type, Context const& context) const { - return type.original_type.visit(visitor_generate{sink, &context, type.c_type, false, is_return}); + return type.original_type.visit(visitor_generate{sink, &context, type.c_type, false, is_return, type.is_ptr}); } template bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const { return param.type.original_type.visit(visitor_generate{sink, &context, param.type.c_type - , param.direction != attributes::parameter_direction::in, false}); + , param.direction != attributes::parameter_direction::in, false, param.type.is_ptr}); } bool is_return; diff --git a/src/bin/eolian_mono/eolian/mono/type_impl.hh b/src/bin/eolian_mono/eolian/mono/type_impl.hh index 3d3950c172..9b56805b99 100644 --- a/src/bin/eolian_mono/eolian/mono/type_impl.hh +++ b/src/bin/eolian_mono/eolian/mono/type_impl.hh @@ -62,6 +62,7 @@ struct visitor_generate std::string c_type; bool is_out; bool is_return; + bool is_ptr; typedef visitor_generate visitor_type; typedef bool result_type; @@ -102,6 +103,7 @@ struct visitor_generate , {"ptrdiff", nullptr, [&] { return replace_base_integer(regular); }} , {"intptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr"); }} + , {"uintptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr"); }} , {"void_ptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr"); }} , {"void", nullptr, [&] { diff --git a/src/bindings/mono/eina_mono/eina_common.cs b/src/bindings/mono/eina_mono/eina_common.cs index 05a562595c..fe4e3ecabb 100644 --- a/src/bindings/mono/eina_mono/eina_common.cs +++ b/src/bindings/mono/eina_mono/eina_common.cs @@ -86,6 +86,36 @@ public static class MemoryNative { } } +[StructLayout(LayoutKind.Sequential)] +public struct ConvertWrapper +{ + public T val; +} + +public static class PrimitiveConversion +{ + public static T PointerToManaged(IntPtr nat) + { + if (nat == IntPtr.Zero) + { + eina.Log.Error("Null pointer for primitive type."); + return default(T); + } + + var w = Marshal.PtrToStructure >(nat); + return w.val; + } + + public static IntPtr ManagedToPointerAlloc(T man) + { + GCHandle pinnedData = GCHandle.Alloc(man, GCHandleType.Pinned); + IntPtr ptr = pinnedData.AddrOfPinnedObject(); + IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf()); + pinnedData.Free(); + return nat; + } +} + public static class StringConversion { public static IntPtr ManagedStringToNativeUtf8Alloc(string managedString) diff --git a/src/bindings/mono/eina_mono/eina_container_common.cs b/src/bindings/mono/eina_mono/eina_container_common.cs index 6cdafdc836..a264ed7577 100644 --- a/src/bindings/mono/eina_mono/eina_container_common.cs +++ b/src/bindings/mono/eina_mono/eina_container_common.cs @@ -18,12 +18,6 @@ public static class ContainerCommonData public static IBaseElementTraits intPtrTraits = null; } -[StructLayout(LayoutKind.Sequential)] -public struct ConvertWrapper -{ - public T Val {get;set;} -} - [StructLayout(LayoutKind.Sequential)] public struct InlistMem { @@ -339,11 +333,7 @@ public abstract class PrimitiveElementTraits public IntPtr ManagedToNativeAlloc(T man) { - GCHandle pinnedData = GCHandle.Alloc(man, GCHandleType.Pinned); - IntPtr ptr = pinnedData.AddrOfPinnedObject(); - IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf()); - pinnedData.Free(); - return nat; + return PrimitiveConversion.ManagedToPointerAlloc(man); } public IntPtr ManagedToNativeAllocInlistNode(T man) @@ -394,8 +384,7 @@ public abstract class PrimitiveElementTraits eina.Log.Error("Null pointer on primitive/struct container."); return default(T); } - var w = Marshal.PtrToStructure >(nat); - return w.Val; + return PrimitiveConversion.PointerToManaged(nat); } public T NativeToManagedRef(IntPtr nat)