forked from enlightenment/efl
eolian_mono: fix handling of regular ptr() types
This commit is contained in:
parent
b55542889b
commit
00fb5b228a
|
@ -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)
|
inline bool is_struct_blacklisted(std::string const& full_name)
|
||||||
{
|
{
|
||||||
return full_name == "Efl.Event.Description"
|
return full_name == "Efl.Event.Description"
|
||||||
// || full_name == "Eina.File"
|
|
||||||
|| full_name == "Eina.Binbuf"
|
|| full_name == "Eina.Binbuf"
|
||||||
|| full_name == "Eina.Slice"
|
|| full_name == "Eina.Slice"
|
||||||
|| full_name == "Eina.Rw_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);
|
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<std::string> 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
|
#endif
|
||||||
|
|
|
@ -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")
|
return as_generator(*(lower_case[string] << ".") << string << "_StructInternal")
|
||||||
.generate(sink, std::make_tuple(eolian_mono::escape_namespace(regular.namespaces), regular.base_type), *context);
|
.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;
|
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<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr}(r);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return}(regular);
|
return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr}(regular);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool operator()(attributes::klass_name klass_name) const
|
bool operator()(attributes::klass_name klass_name) const
|
||||||
{
|
{
|
||||||
return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return}(klass_name);
|
return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr}(klass_name);
|
||||||
// return as_generator(" System.IntPtr").generate(sink, attributes::unused, *context);
|
// return as_generator(" System.IntPtr").generate(sink, attributes::unused, *context);
|
||||||
}
|
}
|
||||||
bool operator()(attributes::complex_type_def const& complex) const
|
bool operator()(attributes::complex_type_def const& complex) const
|
||||||
|
@ -259,7 +266,7 @@ struct marshall_type_visitor_generate
|
||||||
}
|
}
|
||||||
|
|
||||||
//return default_match(complex);
|
//return default_match(complex);
|
||||||
return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return}(complex);
|
return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr}(complex);
|
||||||
// return as_generator(" System.IntPtr").generate(sink, attributes::unused, *context);
|
// return as_generator(" System.IntPtr").generate(sink, attributes::unused, *context);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -269,6 +269,9 @@ inline bool param_should_use_out_var(attributes::parameter_def const& param, boo
|
||||||
if (need_struct_conversion(regular))
|
if (need_struct_conversion(regular))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (param.type.is_ptr && need_pointer_conversion(regular))
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,6 +317,9 @@ inline bool param_should_use_in_var(attributes::parameter_def const& param, bool
|
||||||
if (need_struct_conversion(regular))
|
if (need_struct_conversion(regular))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (param.type.is_ptr && need_pointer_conversion(regular))
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,7 +507,13 @@ struct native_convert_in_variable_generator
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
auto regular = efl::eina::get<attributes::regular_type_def>(¶m.type.original_type);
|
auto regular = efl::eina::get<attributes::regular_type_def>(¶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(
|
return as_generator(
|
||||||
"var " << string << " = " << type << "_StructConvertion.ToExternal(" << escape_keyword(param.param_name) << ");\n"
|
"var " << string << " = " << type << "_StructConvertion.ToExternal(" << escape_keyword(param.param_name) << ");\n"
|
||||||
|
@ -563,7 +575,13 @@ struct convert_in_variable_generator
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
auto regular = efl::eina::get<attributes::regular_type_def>(¶m.type.original_type);
|
auto regular = efl::eina::get<attributes::regular_type_def>(¶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(
|
return as_generator(
|
||||||
"var " << string << " = " << type << "_StructConvertion.ToInternal(" << escape_keyword(param.param_name) << ");\n"
|
"var " << string << " = " << type << "_StructConvertion.ToInternal(" << escape_keyword(param.param_name) << ");\n"
|
||||||
|
@ -651,7 +669,13 @@ struct convert_out_variable_generator
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
auto regular = efl::eina::get<attributes::regular_type_def>(¶m.type.original_type);
|
auto regular = efl::eina::get<attributes::regular_type_def>(¶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(
|
return as_generator(
|
||||||
"var " << string << " = new " << marshall_type << "();\n"
|
"var " << string << " = new " << marshall_type << "();\n"
|
||||||
|
@ -718,7 +742,13 @@ struct native_convert_out_variable_generator
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
auto regular = efl::eina::get<attributes::regular_type_def>(¶m.type.original_type);
|
auto regular = efl::eina::get<attributes::regular_type_def>(¶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, "const char *", !WANT_OWN, WANT_OUT)
|
||||||
|| param_is_acceptable(param, "Eina_Stringshare *", !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;
|
return true;
|
||||||
|
|
||||||
auto regular = efl::eina::get<attributes::regular_type_def>(¶m.type.original_type);
|
auto regular = efl::eina::get<attributes::regular_type_def>(¶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(
|
return as_generator(
|
||||||
string << " = " << type << "_StructConvertion.ToExternal(" << out_variable_name(param.param_name) << ");\n"
|
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
|
bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const
|
||||||
{
|
{
|
||||||
auto regular = efl::eina::get<attributes::regular_type_def>(&ret_type.original_type);
|
auto regular = efl::eina::get<attributes::regular_type_def>(&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 as_generator(
|
||||||
"return " << type << "_StructConvertion.ToExternal(_ret_var);\n"
|
"return " << type << "_StructConvertion.ToExternal(_ret_var);\n"
|
||||||
|
@ -956,7 +998,13 @@ struct native_convert_out_assign_generator
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
auto regular = efl::eina::get<attributes::regular_type_def>(¶m.type.original_type);
|
auto regular = efl::eina::get<attributes::regular_type_def>(¶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(
|
return as_generator(
|
||||||
string << " = " << type << "_StructConvertion.ToInternal(" << string << ");\n"
|
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
|
bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const
|
||||||
{
|
{
|
||||||
auto regular = efl::eina::get<attributes::regular_type_def>(&ret_type.original_type);
|
auto regular = efl::eina::get<attributes::regular_type_def>(&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 as_generator(
|
||||||
"return " << type << "_StructConvertion.ToInternal(_ret_var);\n"
|
"return " << type << "_StructConvertion.ToInternal(_ret_var);\n"
|
||||||
|
|
|
@ -156,6 +156,13 @@ struct to_internal_field_convert_generator
|
||||||
.generate(sink, std::make_tuple(field_name, field_name), context))
|
.generate(sink, std::make_tuple(field_name, field_name), context))
|
||||||
return false;
|
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))
|
else if (need_struct_conversion(regular))
|
||||||
{
|
{
|
||||||
if (!as_generator(
|
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))
|
.generate(sink, std::make_tuple(field_name, field.type, field_name), context))
|
||||||
return false;
|
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))
|
else if (need_struct_conversion(regular))
|
||||||
{
|
{
|
||||||
if (!as_generator(
|
if (!as_generator(
|
||||||
|
|
|
@ -20,13 +20,13 @@ struct type_generator
|
||||||
template <typename OutputIterator, typename Context>
|
template <typename OutputIterator, typename Context>
|
||||||
bool generate(OutputIterator sink, attributes::type_def const& type, Context const& context) const
|
bool generate(OutputIterator sink, attributes::type_def const& type, Context const& context) const
|
||||||
{
|
{
|
||||||
return type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, type.c_type, false, is_return});
|
return type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, type.c_type, false, is_return, type.is_ptr});
|
||||||
}
|
}
|
||||||
template <typename OutputIterator, typename Context>
|
template <typename OutputIterator, typename Context>
|
||||||
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
|
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
|
||||||
{
|
{
|
||||||
return param.type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, param.type.c_type
|
return param.type.original_type.visit(visitor_generate<OutputIterator, Context>{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;
|
bool is_return;
|
||||||
|
|
|
@ -62,6 +62,7 @@ struct visitor_generate
|
||||||
std::string c_type;
|
std::string c_type;
|
||||||
bool is_out;
|
bool is_out;
|
||||||
bool is_return;
|
bool is_return;
|
||||||
|
bool is_ptr;
|
||||||
|
|
||||||
typedef visitor_generate<OutputIterator, Context> visitor_type;
|
typedef visitor_generate<OutputIterator, Context> visitor_type;
|
||||||
typedef bool result_type;
|
typedef bool result_type;
|
||||||
|
@ -102,6 +103,7 @@ struct visitor_generate
|
||||||
|
|
||||||
, {"ptrdiff", nullptr, [&] { return replace_base_integer<ptrdiff_t>(regular); }}
|
, {"ptrdiff", nullptr, [&] { return replace_base_integer<ptrdiff_t>(regular); }}
|
||||||
, {"intptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr"); }}
|
, {"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_ptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr"); }}
|
||||||
, {"void", nullptr, [&]
|
, {"void", nullptr, [&]
|
||||||
{
|
{
|
||||||
|
|
|
@ -86,6 +86,36 @@ public static class MemoryNative {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct ConvertWrapper<T>
|
||||||
|
{
|
||||||
|
public T val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PrimitiveConversion
|
||||||
|
{
|
||||||
|
public static T PointerToManaged<T>(IntPtr nat)
|
||||||
|
{
|
||||||
|
if (nat == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
eina.Log.Error("Null pointer for primitive type.");
|
||||||
|
return default(T);
|
||||||
|
}
|
||||||
|
|
||||||
|
var w = Marshal.PtrToStructure<eina.ConvertWrapper<T> >(nat);
|
||||||
|
return w.val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IntPtr ManagedToPointerAlloc<T>(T man)
|
||||||
|
{
|
||||||
|
GCHandle pinnedData = GCHandle.Alloc(man, GCHandleType.Pinned);
|
||||||
|
IntPtr ptr = pinnedData.AddrOfPinnedObject();
|
||||||
|
IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<T>());
|
||||||
|
pinnedData.Free();
|
||||||
|
return nat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class StringConversion
|
public static class StringConversion
|
||||||
{
|
{
|
||||||
public static IntPtr ManagedStringToNativeUtf8Alloc(string managedString)
|
public static IntPtr ManagedStringToNativeUtf8Alloc(string managedString)
|
||||||
|
|
|
@ -18,12 +18,6 @@ public static class ContainerCommonData
|
||||||
public static IBaseElementTraits<IntPtr> intPtrTraits = null;
|
public static IBaseElementTraits<IntPtr> intPtrTraits = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public struct ConvertWrapper<T>
|
|
||||||
{
|
|
||||||
public T Val {get;set;}
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct InlistMem
|
public struct InlistMem
|
||||||
{
|
{
|
||||||
|
@ -339,11 +333,7 @@ public abstract class PrimitiveElementTraits<T>
|
||||||
|
|
||||||
public IntPtr ManagedToNativeAlloc(T man)
|
public IntPtr ManagedToNativeAlloc(T man)
|
||||||
{
|
{
|
||||||
GCHandle pinnedData = GCHandle.Alloc(man, GCHandleType.Pinned);
|
return PrimitiveConversion.ManagedToPointerAlloc(man);
|
||||||
IntPtr ptr = pinnedData.AddrOfPinnedObject();
|
|
||||||
IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<T>());
|
|
||||||
pinnedData.Free();
|
|
||||||
return nat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IntPtr ManagedToNativeAllocInlistNode(T man)
|
public IntPtr ManagedToNativeAllocInlistNode(T man)
|
||||||
|
@ -394,8 +384,7 @@ public abstract class PrimitiveElementTraits<T>
|
||||||
eina.Log.Error("Null pointer on primitive/struct container.");
|
eina.Log.Error("Null pointer on primitive/struct container.");
|
||||||
return default(T);
|
return default(T);
|
||||||
}
|
}
|
||||||
var w = Marshal.PtrToStructure<eina.ConvertWrapper<T> >(nat);
|
return PrimitiveConversion.PointerToManaged<T>(nat);
|
||||||
return w.Val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public T NativeToManagedRef(IntPtr nat)
|
public T NativeToManagedRef(IntPtr nat)
|
||||||
|
|
Loading…
Reference in New Issue