diff --git a/src/bin/eolian_cxx/eolian_wrappers.hh b/src/bin/eolian_cxx/eolian_wrappers.hh index 3dcb5e3c6b..d56379393f 100644 --- a/src/bin/eolian_cxx/eolian_wrappers.hh +++ b/src/bin/eolian_cxx/eolian_wrappers.hh @@ -348,7 +348,9 @@ parameter_type(Eolian_Function_Parameter const& parameter, assert(!type.empty()); if (parameter_is_out(parameter)) { - type = { efl::eolian::type_to_native(type) }; + if (type.front().native == "char *") + type = { efl::eolian::type_to_native(type) }; + type.front().is_out = true; type.front().native += "*"; } if (parameter_is_const(parameter, func_type)) diff --git a/src/bindings/eo_cxx/eo_cxx_interop.hh b/src/bindings/eo_cxx/eo_cxx_interop.hh index fa3e44b282..d8292961f1 100644 --- a/src/bindings/eo_cxx/eo_cxx_interop.hh +++ b/src/bindings/eo_cxx/eo_cxx_interop.hh @@ -13,12 +13,6 @@ namespace efl { namespace eolian { //// From C++ to C -inline Eo* -to_c(efl::eo::base const& x) -{ - return x._eo_ptr(); -} - inline const char* to_c(std::string const& x) { @@ -45,10 +39,38 @@ to_c(bool* x) } template -T to_c(T const& v, typename std::enable_if::value>::type* = 0) +T to_c(T const& v, typename std::enable_if::value>::type* = 0) { return v; } + +template +Eo* to_c(T const& v, typename std::enable_if::value>::type* = 0) +{ + return v._eo_ptr(); +} + +template +Eo** to_c(T* v, typename std::enable_if::value>::type* = 0) +{ + static_assert(sizeof(T) == sizeof(Eo*), ""); + return static_cast(static_cast(v)); +} + +template +R to_native(T const& v) +{ + static_assert(sizeof(T) == sizeof(R), ""); + return v.native_handle(); +} + +template +R to_native(T* v) +{ + static_assert(sizeof(T) == sizeof(typename std::remove_pointer::type), ""); + return static_cast(static_cast(v)); +} + //// From C to C++ diff --git a/src/lib/eolian_cxx/eo_types.hh b/src/lib/eolian_cxx/eo_types.hh index 92237790d2..15f88e21fd 100644 --- a/src/lib/eolian_cxx/eo_types.hh +++ b/src/lib/eolian_cxx/eo_types.hh @@ -33,6 +33,7 @@ struct eolian_type , category(unknown_) , is_const(false) , is_own(false) + , is_out(false) , binding() , includes() {} @@ -47,6 +48,7 @@ struct eolian_type , category(category_) , is_const(is_const_) , is_own(is_own_) + , is_out(false) , binding(binding_) , includes(includes_) { @@ -66,6 +68,7 @@ struct eolian_type category_type category; bool is_const; bool is_own; + bool is_out; std::string binding; includes_container_type includes; }; @@ -94,6 +97,19 @@ type_is_binding(eolian_type_instance const& type) return type_is_binding(type.front()); } +inline bool +type_is_out(eolian_type const& type) +{ + return type.is_out; +} + +inline bool +type_is_out(eolian_type_instance const& type) +{ + assert(!type.empty()); + return type_is_out(type.front()); +} + inline eolian_type type_to_native(eolian_type const& type) { @@ -122,6 +138,13 @@ type_is_complex(eolian_type const& type) return type.category == eolian_type::complex_; } +inline bool +type_is_complex(eolian_type_instance const& type_ins) +{ + assert(!type_ins.empty()); + return type_is_complex(type_ins.front()); +} + template inline bool type_is_callback(T const&); diff --git a/src/lib/eolian_cxx/grammar/type_generator.hh b/src/lib/eolian_cxx/grammar/type_generator.hh index fcd16005c8..94e91c088b 100644 --- a/src/lib/eolian_cxx/grammar/type_generator.hh +++ b/src/lib/eolian_cxx/grammar/type_generator.hh @@ -47,10 +47,12 @@ operator<<(std::ostream& out, efl::eolian::grammar::reinterpret_type const& x) std::string res; for (auto rit = x._list.rbegin(), last = x._list.rend(); rit != last; ++rit) { - if (type_is_complex(*rit)) - res = (*rit).binding + "< " + res + " >"; + eolian_type const& t = *rit; + if (type_is_complex(t)) + res = t.binding + "< " + res + " >" + (t.is_out ? "*" : ""); else - res = type_is_binding(*rit) ? (*rit).binding : (*rit).native; + res = type_is_binding(t) ? t.binding + (t.is_out ? "*" : "") + : t.native; } assert(!res.empty()); return out << res; @@ -191,6 +193,8 @@ operator<<(std::ostream& out, to_c const& x) if (type_is_callback(x._type)) out << "efl::eolian::get_callback<" << type_to_native_str(x._type) << ", " << parameter_no_ref_type(x._type, x._varname) << " >()"; + else if (type_is_complex(x._type) && type_is_binding(x._type)) + out << "efl::eolian::to_native<" << c_type(x._type) << ">(" << x._varname << ")"; else if (type_is_binding(x._type)) out << "efl::eolian::to_c(" << x._varname << ")"; else