Added BSTR support for Win32
authorJonathan Chambers <joncham@gmail.com>
Wed, 3 May 2006 02:54:45 +0000 (02:54 -0000)
committerJonathan Chambers <joncham@gmail.com>
Wed, 3 May 2006 02:54:45 +0000 (02:54 -0000)
svn path=/trunk/mono/; revision=60200

configure.in
mono/metadata/icall.c
mono/metadata/marshal.c
mono/metadata/marshal.h
mono/metadata/metadata.h

index 00647466e244c0ef4dd1eb9b9044ab368bdf44c4..ec5ac8d5c69b3476e5e37061edd1d903a827eab6 100644 (file)
@@ -1334,6 +1334,7 @@ else
        AC_CHECK_LIB(ws2_32, main, LIBS="$LIBS -lws2_32", AC_ERROR(bad mingw install?))
        AC_CHECK_LIB(psapi, main, LIBS="$LIBS -lpsapi", AC_ERROR(bad mingw install?))
        AC_CHECK_LIB(ole32, main, LIBS="$LIBS -lole32", AC_ERROR(bad mingw install?))
+       AC_CHECK_LIB(oleaut32, main, LIBS="$LIBS -loleaut32", AC_ERROR(bad mingw install?))
 
        dnl *********************************
        dnl *** Check for struct ip_mreqn ***
index 41b3ee3f809a72dc95fffb3679a063b0a74d96d7..a64cc0160317dae19b8cbb2bdfe77a6c44a21d51 100644 (file)
@@ -6913,6 +6913,7 @@ static const IcallEntry marshal_icalls [] = {
        {"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},
@@ -6937,6 +6938,7 @@ static const IcallEntry marshal_icalls [] = {
        {"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},
index 3667ed1a6b74b44939c4e247bf2f70f5e22b8127..65042a7d5a67615156f7a439376457955228de18 100644 (file)
@@ -104,6 +104,12 @@ mono_marshal_string_to_utf16 (MonoString *s);
 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);
 
@@ -171,6 +177,8 @@ mono_marshal_init (void)
                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);
@@ -603,8 +611,35 @@ mono_string_to_ansibstr (MonoString *string_obj)
 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
@@ -1347,6 +1382,8 @@ conv_to_icall (MonoMarshalConv conv)
                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;
@@ -1924,6 +1961,8 @@ mono_marshal_get_string_to_ptr_conv (MonoMethodPInvoke *piinfo, MonoMarshalSpec
                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;
        }
@@ -1963,6 +2002,8 @@ mono_marshal_get_ptr_to_string_conv (MonoMethodPInvoke *piinfo, MonoMarshalSpec
                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;
        }
@@ -4932,12 +4973,22 @@ emit_marshal_string (EmitMarshalContext *m, int argnum, MonoType *t,
                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;
@@ -4958,7 +5009,10 @@ emit_marshal_string (EmitMarshalContext *m, int argnum, MonoType *t,
 
                /* 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:
@@ -7840,10 +7894,23 @@ ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringBSTR (gpointer ptr)
 {
        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 
index 945703b8d764b704d8d40f1cb634650818ecaba2..7d47bbf8d6476a749438590aa62952b6ba8e22a0 100644 (file)
@@ -329,6 +329,9 @@ ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure_type (gpointer s
 int
 ves_icall_System_Runtime_InteropServices_Marshal_OffsetOf (MonoReflectionType *type, MonoString *field_name);
 
+gpointer
+ves_icall_System_Runtime_InteropServices_Marshal_StringToBSTR (MonoString *string);
+
 gpointer
 ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi (MonoString *string);
 
@@ -350,6 +353,9 @@ ves_icall_System_Runtime_InteropServices_Marshal_AllocHGlobal (int size);
 void
 ves_icall_System_Runtime_InteropServices_Marshal_FreeHGlobal (void *ptr);
 
+void
+ves_icall_System_Runtime_InteropServices_Marshal_FreeBSTR (void *ptr);
+
 void*
 ves_icall_System_Runtime_InteropServices_Marshal_UnsafeAddrOfPinnedArrayElement (MonoArray *arrayobj, int index);
 
index f5fadb9f3efe2bd3d3ba8bfd964a51c36f8acae6..1149c4082b13b33006c73672c300c43cc654555c 100644 (file)
@@ -170,7 +170,8 @@ typedef enum {
        MONO_MARSHAL_CONV_OBJECT_STRUCT,
        MONO_MARSHAL_CONV_DEL_FTN,
        MONO_MARSHAL_CONV_FTN_DEL,
-       MONO_MARSHAL_FREE_ARRAY
+       MONO_MARSHAL_FREE_ARRAY,
+       MONO_MARSHAL_CONV_BSTR_STR
 } MonoMarshalConv;
 
 typedef struct {