#include <string.h>
#include <errno.h>
+#if defined(HOST_WIN32)
+#include <oleauto.h>
+#endif
+
/*
Code shared between the DISABLE_COM and !DISABLE_COM
*/
mono_register_jit_icall (func, name, sig, save);
}
+gpointer
+mono_string_to_bstr(MonoString* ptr)
+{
+ if (!ptr)
+ return NULL;
+
+ return mono_ptr_to_bstr(mono_string_chars(ptr), mono_string_length(ptr));
+}
+
#ifndef DISABLE_COM
#define OPDEF(a,b,c,d,e,f,g,h,i,j) \
static GENERATE_GET_CLASS_WITH_CACHE (interface_type_attribute, System.Runtime.InteropServices, InterfaceTypeAttribute)
static GENERATE_GET_CLASS_WITH_CACHE (guid_attribute, System.Runtime.InteropServices, GuidAttribute)
-static GENERATE_GET_CLASS_WITH_CACHE (com_visible_attribute, System.Runtime.InteropServices, ComVisibleAttribute)
/* Upon creation of a CCW, only allocate a weak handle and set the
* reference count to 0. If the unmanaged client code decides to addref and
static gpointer
cominterop_get_ccw (MonoObject* object, MonoClass* itf);
+static gpointer
+cominterop_get_ccw_checked (MonoObject *object, MonoClass *itf, MonoError *error);
+
+
static MonoObject*
cominterop_get_ccw_object (MonoCCWInterface* ccw_entry, gboolean verify);
register_icall (cominterop_get_interface, "cominterop_get_interface", "ptr object ptr int32", 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_string_from_bstr_icall, "mono_string_from_bstr_icall", "obj ptr", FALSE);
register_icall (mono_free_bstr, "mono_free_bstr", "void ptr", FALSE);
register_icall (cominterop_type_from_handle, "cominterop_type_from_handle", "object ptr", FALSE);
void
mono_mb_emit_cominterop_call (MonoMethodBuilder *mb, MonoMethodSignature *sig, MonoMethod* method)
{
+#ifndef DISABLE_JIT
// get function pointer from 1st arg, the COM interface pointer
mono_mb_emit_ldarg (mb, 0);
mono_mb_emit_icon (mb, cominterop_get_com_slot_for_method (method));
mono_mb_emit_calli (mb, sig);
mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
mono_mb_emit_byte (mb, CEE_MONO_RESTORE_LMF);
+#endif /* DISABLE_JIT */
}
void
mono_cominterop_emit_ptr_to_object_conv (MonoMethodBuilder *mb, MonoType *type, MonoMarshalConv conv, MonoMarshalSpec *mspec)
{
+#ifndef DISABLE_JIT
switch (conv) {
case MONO_MARSHAL_CONV_OBJECT_INTERFACE:
case MONO_MARSHAL_CONV_OBJECT_IUNKNOWN:
default:
g_assert_not_reached ();
}
+#endif /* DISABLE_JIT */
}
void
mono_cominterop_emit_object_to_ptr_conv (MonoMethodBuilder *mb, MonoType *type, MonoMarshalConv conv, MonoMarshalSpec *mspec)
{
+#ifndef DISABLE_JIT
switch (conv) {
case MONO_MARSHAL_CONV_OBJECT_INTERFACE:
case MONO_MARSHAL_CONV_OBJECT_IDISPATCH:
default:
g_assert_not_reached ();
}
+#endif /* DISABLE_JIT */
}
/**
sig = mono_method_signature (method);
mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_COMINTEROP);
+#ifndef DISABLE_JIT
/* if method klass is import, that means method
* is really a com call. let interop system emit it.
*/
imported classes is not yet implemented.");
mono_mb_emit_exception (mb, "NotSupportedException", msg);
}
+#endif /* DISABLE_JIT */
+
csig = mono_metadata_signature_dup_full (method->klass->image, sig);
csig->pinvoke = 0;
res = mono_mb_create_and_cache (cache, method,
mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_COMINTEROP_INVOKE);
+#ifndef DISABLE_JIT
/* get real proxy object, which is a ComInteropProxy in this case*/
mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg);
mono_mb_emit_ldarg (mb, 0);
mono_marshal_emit_thread_interrupt_checkpoint (mb);
mono_mb_emit_byte (mb, CEE_RET);
+#endif /* DISABLE_JIT */
res = mono_mb_create_and_cache (cache, method, mb, sig, sig->param_count + 16);
mono_mb_free (mb);
if (!marshal_release)
marshal_release = mono_class_get_method_from_name (mono_defaults.marshal_class, "Release", 1);
+#ifdef DISABLE_JIT
+ switch (action) {
+ case MARSHAL_ACTION_CONV_IN:
+ *conv_arg_type = &mono_defaults.int_class->byval_arg;
+ break;
+ case MARSHAL_ACTION_MANAGED_CONV_IN:
+ *conv_arg_type = &mono_defaults.int_class->byval_arg;
+ break;
+ default:
+ break;
+ }
+#else
switch (action) {
case MARSHAL_ACTION_CONV_IN: {
guint32 pos_null = 0;
default:
g_assert_not_reached ();
}
+#endif /* DISABLE_JIT */
return conv_arg;
}
cominterop_set_hr_error (error, MONO_E_NOINTERFACE);
return NULL;
}
- return cominterop_get_ccw (object, mono_class_get_idispatch_class ());
+ return cominterop_get_ccw_checked (object, mono_class_get_idispatch_class (), error);
}
}
ves_icall_System_Runtime_InteropServices_Marshal_GetIUnknownForObjectInternal (MonoObject* object)
{
#ifndef DISABLE_COM
+ MonoError error;
+
if (!object)
return NULL;
return ((MonoComInteropProxy*)real_proxy)->com_object->iunknown;
}
else {
- return cominterop_get_ccw (object, mono_class_get_iunknown_class ());
+ void* ccw_entry = cominterop_get_ccw_checked (object, mono_class_get_iunknown_class (), &error);
+ mono_error_set_pending_exception (&error);
+ return ccw_entry;
}
#else
g_assert_not_reached ();
ves_icall_System_Runtime_InteropServices_Marshal_GetCCW (MonoObject* object, MonoReflectionType* type)
{
#ifndef DISABLE_COM
+ MonoError error;
MonoClass* klass = NULL;
void* itf = NULL;
g_assert (type);
return NULL;
}
- itf = cominterop_get_ccw (object, klass);
- g_assert (itf);
+ itf = cominterop_get_ccw_checked (object, klass, &error);
+ mono_error_set_pending_exception (&error);
return itf;
#else
g_assert_not_reached ();
* Constructor does not need to be called. Will be called later.
*/
MonoVTable *vtable = mono_class_vtable_full (domain, klass, &error);
- mono_error_raise_exception (&error);
+ if (mono_error_set_pending_exception (&error))
+ return NULL;
obj = mono_object_new_alloc_specific_checked (vtable, &error);
- mono_error_raise_exception (&error);
+ if (mono_error_set_pending_exception (&error))
+ return NULL;
return obj;
}
}
/**
- * cominterop_get_ccw:
+ * cominterop_get_ccw_checked:
* @object: a pointer to the object
* @itf: interface type needed
+ * @error: set on error
*
* Returns: a value indicating if the object is a
- * Runtime Callable Wrapper (RCW) for a COM object
+ * Runtime Callable Wrapper (RCW) for a COM object.
+ * On failure returns NULL and sets @error.
*/
static gpointer
-cominterop_get_ccw (MonoObject* object, MonoClass* itf)
+cominterop_get_ccw_checked (MonoObject* object, MonoClass* itf, MonoError *error)
{
- MonoError error;
int i;
MonoCCW *ccw = NULL;
MonoCCWInterface* ccw_entry = NULL;
GList *ccw_list, *ccw_list_item;
MonoCustomAttrInfo *cinfo = NULL;
+ mono_error_init (error);
+
if (!object)
return NULL;
g_hash_table_insert (ccw_hash, GINT_TO_POINTER (mono_object_hash (object)), ccw_list);
mono_cominterop_unlock ();
/* register for finalization to clean up ccw */
- mono_object_register_finalizer (object, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_object_register_finalizer (object);
}
- cinfo = mono_custom_attrs_from_class_checked (itf, &error);
- mono_error_assert_ok (&error);
+ cinfo = mono_custom_attrs_from_class_checked (itf, error);
+ mono_error_assert_ok (error);
if (cinfo) {
static MonoClass* coclass_attribute = NULL;
if (!coclass_attribute)
mspecs [0] = NULL;
}
+#ifndef DISABLE_JIT
/* skip visiblity since we call internal methods */
mb->skip_visibility = TRUE;
+#endif
cominterop_setup_marshal_context (&m, adjust_method);
m.mb = mb;
wrapper_method = mono_mb_create_method (mb, m.csig, m.csig->param_count + 16);
mono_cominterop_unlock ();
- vtable [vtable_index--] = mono_compile_method (wrapper_method);
+ vtable [vtable_index--] = mono_compile_method_checked (wrapper_method, error);
-
+ // cleanup, then error out if compile_method failed
for (param_index = sig_adjusted->param_count; param_index >= 0; param_index--)
if (mspecs [param_index])
mono_metadata_free_marshal_spec (mspecs [param_index]);
g_free (mspecs);
+ return_val_if_nok (error, NULL);
}
ccw_entry = g_new0 (MonoCCWInterface, 1);
return ccw_entry;
}
+/**
+ * cominterop_get_ccw:
+ * @object: a pointer to the object
+ * @itf: interface type needed
+ *
+ * Returns: a value indicating if the object is a
+ * Runtime Callable Wrapper (RCW) for a COM object
+ */
+static gpointer
+cominterop_get_ccw (MonoObject* object, MonoClass* itf)
+{
+ MonoError error;
+ gpointer ccw_entry = cominterop_get_ccw_checked (object, itf, &error);
+ mono_error_set_pending_exception (&error);
+ return ccw_entry;
+}
+
static gboolean
mono_marshal_free_ccw_entry (gpointer key, gpointer value, gpointer user_data)
{
mspecs [0] = NULL;
- if (!preserve_sig) {
+#ifndef DISABLE_JIT
+ if (!preserve_sig)
hr = mono_mb_add_local (mb, &mono_defaults.int32_class->byval_arg);
- }
else if (!MONO_TYPE_IS_VOID (sig->ret))
hr = mono_mb_add_local (mb, sig->ret);
mono_mb_emit_ldloc (mb, hr);
mono_mb_emit_byte (mb, CEE_RET);
+#endif /* DISABLE_JIT */
mono_cominterop_lock ();
res = mono_mb_create_method (mb, sig_native, sig_native->param_count + 16);
#ifdef HOST_WIN32
/* All ccw objects are free threaded */
static int
-cominterop_ccw_getfreethreadedmarshaler (MonoCCW* ccw, MonoObject* object, gpointer* ppv)
+cominterop_ccw_getfreethreadedmarshaler (MonoCCW* ccw, MonoObject* object, gpointer* ppv, MonoError *error)
{
+ mono_error_init (error);
#ifdef HOST_WIN32
if (!ccw->free_marshaler) {
int ret = 0;
gpointer tunk;
- tunk = cominterop_get_ccw (object, mono_class_get_iunknown_class ());
+ tunk = cominterop_get_ccw_checked (object, mono_class_get_iunknown_class (), error);
+ return_val_if_nok (error, MONO_E_NOINTERFACE);
ret = CoCreateFreeThreadedMarshaler (tunk, (LPUNKNOWN*)&ccw->free_marshaler);
}
/* handle IUnknown special */
if (cominterop_class_guid_equal (riid, mono_class_get_iunknown_class ())) {
- *ppv = cominterop_get_ccw (object, mono_class_get_iunknown_class ());
+ *ppv = cominterop_get_ccw_checked (object, mono_class_get_iunknown_class (), &error);
+ mono_error_assert_ok (&error);
/* remember to addref on QI */
cominterop_ccw_addref ((MonoCCWInterface *)*ppv);
return MONO_S_OK;
if (!cominterop_can_support_dispatch (klass))
return MONO_E_NOINTERFACE;
- *ppv = cominterop_get_ccw (object, mono_class_get_idispatch_class ());
+ *ppv = cominterop_get_ccw_checked (object, mono_class_get_idispatch_class (), &error);
+ mono_error_assert_ok (&error);
/* remember to addref on QI */
cominterop_ccw_addref ((MonoCCWInterface *)*ppv);
return MONO_S_OK;
#ifdef HOST_WIN32
/* handle IMarshal special */
if (0 == memcmp (riid, &MONO_IID_IMarshal, sizeof (IID))) {
- return cominterop_ccw_getfreethreadedmarshaler (ccw, object, ppv);
+ int res = cominterop_ccw_getfreethreadedmarshaler (ccw, object, ppv, &error);
+ mono_error_assert_ok (&error);
+ return res;
}
#endif
klass_iter = klass;
klass_iter = klass_iter->parent;
}
if (itf) {
- *ppv = cominterop_get_ccw (object, itf);
+ *ppv = cominterop_get_ccw_checked (object, itf, &error);
+ if (!is_ok (&error)) {
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ return MONO_E_NOINTERFACE;
+ }
/* remember to addref on QI */
cominterop_ccw_addref ((MonoCCWInterface *)*ppv);
return MONO_S_OK;
}
gpointer
-mono_string_to_bstr (MonoString *string_obj)
+mono_ptr_to_bstr(gpointer ptr, int slen)
{
- if (!string_obj)
+ if (!ptr)
return NULL;
#ifdef HOST_WIN32
- return SysAllocStringLen (mono_string_chars (string_obj), mono_string_length (string_obj));
+ return SysAllocStringLen (ptr, slen);
#else
if (com_provider == MONO_COM_DEFAULT) {
- int slen = mono_string_length (string_obj);
/* allocate len + 1 utf16 characters plus 4 byte integer for length*/
- char *ret = (char *)g_malloc ((slen + 1) * sizeof(gunichar2) + sizeof(guint32));
+ char *ret = (char *)g_malloc((slen + 1) * sizeof(gunichar2) + sizeof(guint32));
if (ret == NULL)
return NULL;
- memcpy (ret + sizeof(guint32), mono_string_chars (string_obj), slen * sizeof(gunichar2));
- * ((guint32 *) ret) = slen * sizeof(gunichar2);
- ret [4 + slen * sizeof(gunichar2)] = 0;
- ret [5 + slen * sizeof(gunichar2)] = 0;
+ memcpy(ret + sizeof(guint32), ptr, slen * sizeof(gunichar2));
+ *((guint32 *)ret) = slen * sizeof(gunichar2);
+ ret[4 + slen * sizeof(gunichar2)] = 0;
+ ret[5 + slen * sizeof(gunichar2)] = 0;
return ret + 4;
- } else if (com_provider == MONO_COM_MS && init_com_provider_ms ()) {
+ }
+ else if (com_provider == MONO_COM_MS && init_com_provider_ms()) {
gpointer ret = NULL;
gunichar* str = NULL;
- guint32 len;
- len = mono_string_length (string_obj);
- str = g_utf16_to_ucs4 (mono_string_chars (string_obj), len,
+ guint32 len = slen;
+ str = g_utf16_to_ucs4(ptr, len,
NULL, NULL, NULL);
- ret = sys_alloc_string_len_ms (str, len);
+ ret = sys_alloc_string_len_ms(str, len);
g_free(str);
return ret;
- } else {
- g_assert_not_reached ();
+ }
+ else {
+ g_assert_not_reached();
}
#endif
}
mono_string_from_bstr (gpointer bstr)
{
MonoError error;
+ MonoString *result = mono_string_from_bstr_checked (bstr, &error);
+ mono_error_cleanup (&error);
+ return result;
+}
+
+MonoString *
+mono_string_from_bstr_icall (gpointer bstr)
+{
+ MonoError error;
+ MonoString *result = mono_string_from_bstr_checked (bstr, &error);
+ mono_error_set_pending_exception (&error);
+ return result;
+}
+
+MonoString *
+mono_string_from_bstr_checked (gpointer bstr, MonoError *error)
+{
MonoString * res = NULL;
+ mono_error_init (error);
+
if (!bstr)
return NULL;
#ifdef HOST_WIN32
- res = mono_string_new_utf16_checked (mono_domain_get (), bstr, SysStringLen (bstr), &error);
+ res = mono_string_new_utf16_checked (mono_domain_get (), bstr, SysStringLen (bstr), error);
#else
if (com_provider == MONO_COM_DEFAULT) {
- res = mono_string_new_utf16_checked (mono_domain_get (), (const mono_unichar2 *)bstr, *((guint32 *)bstr - 1) / sizeof(gunichar2), &error);
+ res = mono_string_new_utf16_checked (mono_domain_get (), (const mono_unichar2 *)bstr, *((guint32 *)bstr - 1) / sizeof(gunichar2), error);
} else if (com_provider == MONO_COM_MS && init_com_provider_ms ()) {
MonoString* str = NULL;
glong written = 0;
gunichar2* utf16 = NULL;
utf16 = g_ucs4_to_utf16 ((const gunichar *)bstr, sys_string_len_ms (bstr), NULL, &written, NULL);
- str = mono_string_new_utf16_checked (mono_domain_get (), utf16, written, &error);
+ str = mono_string_new_utf16_checked (mono_domain_get (), utf16, written, error);
g_free (utf16);
res = str;
} else {
}
#endif
- mono_error_raise_exception (&error); /* FIXME don't raise here */
return res;
}
{
MonoMethodBuilder *mb = m->mb;
+#ifndef DISABLE_JIT
switch (action) {
-
case MARSHAL_ACTION_CONV_IN: {
-
if (t->attrs & PARAM_ATTRIBUTE_IN) {
/* Generates IL code for the following algorithm:
break;
case MARSHAL_ACTION_CONV_OUT: {
-
if (t->attrs & PARAM_ATTRIBUTE_OUT) {
/* Generates IL code for the following algorithm:
default:
g_assert_not_reached ();
}
+#endif /* DISABLE_JIT */
return conv_arg;
}
return result;
}
+/* This is an icall */
static gboolean
mono_marshal_safearray_begin (gpointer safearray, MonoArray **result, gpointer *indices, gpointer empty, gpointer parameter, gboolean allocateNewArray)
{
hr = mono_marshal_safe_array_get_lbound (safearray, i+1, &lbound);
if (hr < 0) {
cominterop_set_hr_error (&error, hr);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (mono_error_set_pending_exception (&error))
+ return FALSE;
}
if (lbound != 0)
bounded = TRUE;
hr = mono_marshal_safe_array_get_ubound (safearray, i+1, &ubound);
if (hr < 0) {
cominterop_set_hr_error (&error, hr);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (mono_error_set_pending_exception (&error))
+ return FALSE;
}
cursize = ubound-lbound+1;
sizes [i] = cursize;
if (allocateNewArray) {
aklass = mono_bounded_array_class_get (mono_defaults.object_class, dim, bounded);
*result = mono_array_new_full_checked (mono_domain_get (), aklass, sizes, bounds, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (mono_error_set_pending_exception (&error))
+ return FALSE;
} else {
*result = (MonoArray *)parameter;
}
return TRUE;
}
+/* This is an icall */
static
gpointer mono_marshal_safearray_get_value (gpointer safearray, gpointer indices)
{
int hr = SafeArrayPtrOfIndex (safearray, indices, &result);
if (hr < 0) {
cominterop_set_hr_error (&error, hr);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_error_set_pending_exception (&error);
+ return NULL;
}
#else
if (com_provider == MONO_COM_MS && init_com_provider_ms ()) {
int hr = safe_array_ptr_of_index_ms (safearray, (glong *)indices, &result);
if (hr < 0) {
cominterop_set_hr_error (&error, hr);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_error_set_pending_exception (&error);
+ return NULL;
}
} else {
g_assert_not_reached ();
return result;
}
+/* This is an icall */
static
gboolean mono_marshal_safearray_next (gpointer safearray, gpointer indices)
{
hr = mono_marshal_safe_array_get_ubound (safearray, i+1, &ubound);
if (hr < 0) {
cominterop_set_hr_error (&error, hr);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_error_set_pending_exception (&error);
+ return FALSE;
}
if (++pIndices[i] <= ubound) {
hr = mono_marshal_safe_array_get_lbound (safearray, i+1, &lbound);
if (hr < 0) {
cominterop_set_hr_error (&error, hr);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_error_set_pending_exception (&error);
+ return FALSE;
}
pIndices[i] = lbound;
return TRUE;
}
+/* This is an icall */
static
void mono_marshal_safearray_set_value (gpointer safearray, gpointer indices, gpointer value)
{
int hr = SafeArrayPutElement (safearray, indices, value);
if (hr < 0) {
cominterop_set_hr_error (&error, hr);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_error_set_pending_exception (&error);
+ return;
}
#else
if (com_provider == MONO_COM_MS && init_com_provider_ms ()) {
int hr = safe_array_put_element_ms (safearray, (glong *)indices, (void **)value);
if (hr < 0) {
cominterop_set_hr_error (&error, hr);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_error_set_pending_exception (&error);
+ return;
}
} else
g_assert_not_reached ();
emit an exception in the generated IL.
*/
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_string_from_bstr_icall, "mono_string_from_bstr_icall", "obj ptr", FALSE);
register_icall (mono_free_bstr, "mono_free_bstr", "void ptr", FALSE);
}
}
gpointer
-mono_string_to_bstr (MonoString *string_obj)
+mono_ptr_to_bstr (gpointer ptr, int slen)
{
- if (!string_obj)
+ if (!ptr)
return NULL;
#ifdef HOST_WIN32
- return SysAllocStringLen (mono_string_chars (string_obj), mono_string_length (string_obj));
+ return SysAllocStringLen (ptr, slen);
#else
{
- int slen = mono_string_length (string_obj);
/* allocate len + 1 utf16 characters plus 4 byte integer for length*/
char *ret = g_malloc ((slen + 1) * sizeof(gunichar2) + sizeof(guint32));
if (ret == NULL)
return NULL;
- memcpy (ret + sizeof(guint32), mono_string_chars (string_obj), slen * sizeof(gunichar2));
+ memcpy (ret + sizeof(guint32), ptr, slen * sizeof(gunichar2));
* ((guint32 *) ret) = slen * sizeof(gunichar2);
ret [4 + slen * sizeof(gunichar2)] = 0;
ret [5 + slen * sizeof(gunichar2)] = 0;
#endif
}
+
MonoString *
mono_string_from_bstr (gpointer bstr)
{
- MonoString *res = NULL;
MonoError error;
+ MonoString *result = mono_string_from_bstr_checked (bstr, &error);
+ mono_error_cleanup (&error);
+ return result;
+}
+
+MonoString *
+mono_string_from_bstr_icall (gpointer bstr)
+{
+ MonoError error;
+ MonoString *result = mono_string_from_bstr_checked (bstr, &error);
+ mono_error_set_pending_exception (&error);
+ return result;
+}
+
+MonoString *
+mono_string_from_bstr_checked (gpointer bstr, MonoError *error)
+{
+ MonoString *res = NULL;
+ mono_error_init (error);
if (!bstr)
return NULL;
#ifdef HOST_WIN32
- res = mono_string_new_utf16_checked (mono_domain_get (), bstr, SysStringLen (bstr), &error);
+ res = mono_string_new_utf16_checked (mono_domain_get (), bstr, SysStringLen (bstr), error);
#else
- res = mono_string_new_utf16_checked (mono_domain_get (), bstr, *((guint32 *)bstr - 1) / sizeof(gunichar2), &error);
+ res = mono_string_new_utf16_checked (mono_domain_get (), bstr, *((guint32 *)bstr - 1) / sizeof(gunichar2), error);
#endif
- mono_error_raise_exception (&error); /* FIXME don't raise here */
return res;
}
MonoString *
ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringBSTR (gpointer ptr)
{
- return mono_string_from_bstr(ptr);
+ MonoError error;
+ MonoString *result = mono_string_from_bstr_checked (ptr, &error);
+ mono_error_set_pending_exception (&error);
+ return result;
}
gpointer
return mono_string_to_bstr(ptr);
}
+gpointer
+ves_icall_System_Runtime_InteropServices_Marshal_BufferToBSTR (MonoArray* ptr, int len)
+{
+ return mono_ptr_to_bstr (ptr->vector, len);
+}
+
void
ves_icall_System_Runtime_InteropServices_Marshal_FreeBSTR (gpointer ptr)
{