{"AllocCoTaskMem", ves_icall_System_Runtime_InteropServices_Marshal_AllocCoTaskMem},
{"AllocHGlobal", ves_icall_System_Runtime_InteropServices_Marshal_AllocHGlobal},
{"DestroyStructure", ves_icall_System_Runtime_InteropServices_Marshal_DestroyStructure},
+ {"FreeBSTR", ves_icall_System_Runtime_InteropServices_Marshal_FreeBSTR},
{"FreeCoTaskMem", ves_icall_System_Runtime_InteropServices_Marshal_FreeCoTaskMem},
{"FreeHGlobal", ves_icall_System_Runtime_InteropServices_Marshal_FreeHGlobal},
{"GetDelegateForFunctionPointerInternal", ves_icall_System_Runtime_InteropServices_Marshal_GetDelegateForFunctionPointerInternal},
{"ReadInt64", ves_icall_System_Runtime_InteropServices_Marshal_ReadInt64},
{"ReadIntPtr", ves_icall_System_Runtime_InteropServices_Marshal_ReadIntPtr},
{"SizeOf", ves_icall_System_Runtime_InteropServices_Marshal_SizeOf},
+ {"StringToBSTR", ves_icall_System_Runtime_InteropServices_Marshal_StringToBSTR},
{"StringToHGlobalAnsi", ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi},
{"StringToHGlobalAuto", ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi},
{"StringToHGlobalUni", ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalUni},
static gpointer
mono_string_to_lpstr (MonoString *string_obj);
+static MonoString *
+mono_string_from_bstr (gpointer bstr);
+
+static void
+mono_free_bstr (gpointer bstr);
+
static void
mono_byvalarray_to_array (MonoArray *arr, gpointer native_arr, MonoClass *eltype, guint32 elnum);
register_icall (mono_string_to_utf8, "mono_string_to_utf8", "ptr obj", FALSE);
register_icall (mono_string_to_lpstr, "mono_string_to_lpstr", "ptr obj", FALSE);
register_icall (mono_string_to_bstr, "mono_string_to_bstr", "ptr obj", FALSE);
+ register_icall (mono_string_from_bstr, "mono_string_from_bstr", "obj ptr", FALSE);
+ register_icall (mono_free_bstr, "mono_free_bstr", "void ptr", FALSE);
register_icall (mono_string_to_ansibstr, "mono_string_to_ansibstr", "ptr object", FALSE);
register_icall (mono_string_builder_to_utf8, "mono_string_builder_to_utf8", "ptr object", FALSE);
register_icall (mono_string_builder_to_utf16, "mono_string_builder_to_utf16", "ptr object", FALSE);
gpointer
mono_string_to_bstr (MonoString *string_obj)
{
- g_error ("UnmanagedMarshal.AnsiBStr is not implemented.");
+#ifdef PLATFORM_WIN32
+ return SysAllocStringLen (mono_string_chars (string_obj), mono_string_length (string_obj));
+#else
+ g_error ("UnmanagedMarshal.BStr is not implemented.");
return NULL;
+#endif
+}
+
+MonoString *
+mono_string_from_bstr (gpointer bstr)
+{
+#ifdef PLATFORM_WIN32
+ MonoDomain *domain = mono_domain_get ();
+ return mono_string_new_utf16 (domain, bstr, SysStringLen (bstr));
+#else
+ g_error ("UnmanagedMarshal.BStr is not implemented.");
+ return NULL;
+#endif
+}
+
+void
+mono_free_bstr (gpointer bstr)
+{
+#ifdef PLATFORM_WIN32
+ SysFreeString ((BSTR)bstr);
+#else
+ g_error ("Free BSTR is not implemented.");
+ return NULL;
+#endif
}
void
return mono_string_to_lpstr;
case MONO_MARSHAL_CONV_STR_BSTR:
return mono_string_to_bstr;
+ case MONO_MARSHAL_CONV_BSTR_STR:
+ return mono_string_from_bstr;
case MONO_MARSHAL_CONV_STR_TBSTR:
case MONO_MARSHAL_CONV_STR_ANSIBSTR:
return mono_string_to_ansibstr;
return MONO_MARSHAL_CONV_STR_LPSTR;
case MONO_NATIVE_LPTSTR:
return MONO_MARSHAL_CONV_STR_LPTSTR;
+ case MONO_NATIVE_BSTR:
+ return MONO_MARSHAL_CONV_STR_BSTR;
default:
return -1;
}
return MONO_MARSHAL_CONV_LPSTR_STR;
case MONO_NATIVE_LPTSTR:
return MONO_MARSHAL_CONV_LPTSTR_STR;
+ case MONO_NATIVE_BSTR:
+ return MONO_MARSHAL_CONV_BSTR_STR;
default:
return -1;
}
if (t->byref && (t->attrs & PARAM_ATTRIBUTE_OUT)) {
mono_mb_emit_ldarg (mb, argnum);
mono_mb_emit_ldloc (mb, conv_arg);
- mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_LPSTR_STR));
+ if (conv == MONO_MARSHAL_CONV_STR_BSTR) {
+ mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_BSTR_STR));
+ // BSTRs always need freed
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_icall (mb, mono_free_bstr);
+ }
+ else
+ mono_mb_emit_icall (mb, conv_to_icall (MONO_MARSHAL_CONV_LPSTR_STR));
mono_mb_emit_byte (mb, CEE_STIND_I);
} else {
if (mono_marshal_need_free (t, m->piinfo, spec)) {
mono_mb_emit_ldloc (mb, conv_arg);
- mono_mb_emit_icall (mb, mono_marshal_free);
+ if (conv == MONO_MARSHAL_CONV_STR_BSTR)
+ mono_mb_emit_icall (mb, mono_free_bstr);
+ else
+ mono_mb_emit_icall (mb, mono_marshal_free);
}
}
break;
/* free the string */
mono_mb_emit_ldloc (mb, 0);
- mono_mb_emit_icall (mb, g_free);
+ if (conv == MONO_MARSHAL_CONV_BSTR_STR)
+ mono_mb_emit_icall (mb, mono_free_bstr);
+ else
+ mono_mb_emit_icall (mb, g_free);
break;
case MARSHAL_ACTION_MANAGED_CONV_IN:
{
MONO_ARCH_SAVE_REGS;
- g_warning ("PtrToStringBSTR not implemented");
- g_assert_not_reached ();
+ return mono_string_from_bstr(ptr);
+}
- return NULL;
+gpointer
+ves_icall_System_Runtime_InteropServices_Marshal_StringToBSTR (MonoString* ptr)
+{
+ MONO_ARCH_SAVE_REGS;
+
+ return mono_string_to_bstr(ptr);
+}
+
+void
+ves_icall_System_Runtime_InteropServices_Marshal_FreeBSTR (gpointer ptr)
+{
+ MONO_ARCH_SAVE_REGS;
+
+ mono_free_bstr (ptr);
}
guint32