2003-05-12 Dietmar Maurer <dietmar@ximian.com>
authorDietmar Maurer <dietmar@mono-cvs.ximian.com>
Mon, 12 May 2003 16:01:05 +0000 (16:01 -0000)
committerDietmar Maurer <dietmar@mono-cvs.ximian.com>
Mon, 12 May 2003 16:01:05 +0000 (16:01 -0000)
* loader.c (mono_lookup_pinvoke_call): consider Ansi/Unicode
attributes (fix for bug 42021).

svn path=/trunk/mono/; revision=14520

mono/metadata/ChangeLog
mono/metadata/loader.c
mono/metadata/marshal.c
mono/tests/Makefile.am
mono/tests/libtest.c
mono/tests/pinvoke13.cs [new file with mode: 0644]

index 3bf00987d4159205a86cbbe44a78e9a648ffa5c3..168c183c866e103b176d05813b92e2124f16f65e 100644 (file)
@@ -1,3 +1,8 @@
+2003-05-12  Dietmar Maurer  <dietmar@ximian.com>
+
+       * loader.c (mono_lookup_pinvoke_call): consider Ansi/Unicode
+       attributes (fix for bug 42021).
+
 2003-05-12  Dick Porter  <dick@ximian.com>
 
        * gc.c: Don't run finalizers when the finalizer thread is
index 4b790810fba4a93db36d0c9c95ad8bb617be5ac2..25773410e87e93c2db8a4eac239f18e469784868 100644 (file)
@@ -428,7 +428,37 @@ mono_lookup_pinvoke_call (MonoMethod *method)
        }
        g_free (full_name);
 
-       g_module_symbol (gmodule, import, &method->addr); 
+       if (piinfo->piflags & PINVOKE_ATTRIBUTE_NO_MANGLE) {
+               g_module_symbol (gmodule, import, &method->addr); 
+       } else {
+               char *mangled_name;
+               gpointer addr;
+
+               switch (piinfo->piflags & PINVOKE_ATTRIBUTE_CHAR_SET_MASK) {
+               case PINVOKE_ATTRIBUTE_CHAR_SET_UNICODE:
+                       mangled_name = g_strconcat (import, "W", NULL);
+                       printf ("SEARCH %s\n", mangled_name);
+                       g_module_symbol (gmodule, mangled_name, &method->addr); 
+                       g_free (mangled_name);
+
+                       if (!method->addr)
+                               g_module_symbol (gmodule, import, &method->addr); 
+                       break;
+               case PINVOKE_ATTRIBUTE_CHAR_SET_AUTO:
+                       g_module_symbol (gmodule, import, &method->addr); 
+                       break;
+               case PINVOKE_ATTRIBUTE_CHAR_SET_ANSI:
+               default:
+                       mangled_name = g_strconcat (import, "A", NULL);
+                       g_module_symbol (gmodule, mangled_name, &method->addr); 
+                       g_free (mangled_name);
+
+                       if (!method->addr)
+                               g_module_symbol (gmodule, import, &method->addr); 
+                              
+                       break;                                  
+               }
+       }
 
        if (!method->addr) {
                g_warning ("Failed to load function %s from %s", import, scope);
@@ -604,6 +634,7 @@ mono_method_get_marshal_info (MonoMethod *method, MonoMarshalSpec **mspecs)
                                        mspecs [cols [MONO_PARAM_SEQUENCE]]= mono_metadata_parse_marshal_spec (klass->image, tp);
                                }
                        }
+
                        return;
                }
        }
index ebd0e86a2fe8eb390a782e4a3407c4d3fac0eb0e..61103bb62382603135d056548ac8011eec8af4d3 100644 (file)
@@ -2433,6 +2433,7 @@ MonoMethod *
 mono_marshal_get_native_wrapper (MonoMethod *method)
 {
        MonoMethodSignature *sig, *csig;
+       MonoMethodPInvoke *piinfo;
        MonoMethodBuilder *mb;
        MonoMarshalSpec **mspecs;
        MonoMethod *res;
@@ -2463,6 +2464,8 @@ mono_marshal_get_native_wrapper (MonoMethod *method)
        if (pinvoke && !method->addr)
                mono_lookup_pinvoke_call (method);
 
+       piinfo = (MonoMethodPInvoke *)method;
+
        if (!method->addr) {
                mono_mb_emit_exception (mb);
                csig = g_memdup (sig, sigsize);
@@ -2605,7 +2608,20 @@ mono_marshal_get_native_wrapper (MonoMethod *method)
                                        g_assert_not_reached ();
                                }
                        } else {
-                               mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_STR_LPSTR);
+                               switch (piinfo->piflags & PINVOKE_ATTRIBUTE_CHAR_SET_MASK) {
+                               case PINVOKE_ATTRIBUTE_CHAR_SET_ANSI:
+                                       mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_STR_LPSTR);
+                                       break;
+                               case PINVOKE_ATTRIBUTE_CHAR_SET_UNICODE:
+                                       mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_STR_LPWSTR);
+                                       break;
+                               case PINVOKE_ATTRIBUTE_CHAR_SET_AUTO:
+                                       mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_STR_LPTSTR);
+                                       break;
+                               default:
+                                       mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_STR_LPSTR);
+                                       break;                                  
+                               }
                        }
 
                        mono_mb_emit_stloc (mb, tmp_locals [i]);
index d8442049c9977f3ac308a688b46397bc59a57499..9e721f598d217bc83a10fc064dc1a8962620f74f 100644 (file)
@@ -56,6 +56,7 @@ TEST_CS_SRC=                  \
        pinvoke10.cs            \
        pinvoke11.cs            \
        pinvoke12.cs            \
+       pinvoke13.cs            \
        invoke.cs               \
        invoke2.cs              \
        reinit.cs               \
index b1b281bb4a9366d1f2775c128d0eb2a27342b256..e031910be2121d87a6355ab71e9e531c3eb0fc0f 100644 (file)
@@ -289,3 +289,62 @@ mono_test_byvalstr_check (ByValStrStruct* data, char* correctString)
        g_free(data);
        return (ret != 0);
 }
+
+int 
+HexDump(char *data)
+{
+       int i, res = 0;
+       char *p;
+
+       printf ("HEXDUMP DEFAULT VERSION\n");
+
+       p = data;
+       for (i=0; i < 8; ++i)
+       {
+               res += *p;
+               printf("%0x ", (int) *(p++));
+       }
+       putchar('\n');
+
+       return res;
+}
+
+int 
+HexDumpA(char *data)
+{
+       int i, res = 0;
+       char *p;
+
+       printf ("HEXDUMP ANSI VERSION\n");
+
+       p = data;
+       for (i=0; i < 8; ++i)
+       {
+               res += *p;
+               printf("%0x ", (int) *(p++));
+       }
+       putchar('\n');
+
+       return res + 100000;
+}
+
+int 
+HexDump1W(char *data)
+{
+       int i, res = 0;
+       char *p;
+
+       printf ("HEXDUMP UNICODE VERSION\n");
+
+       p = data;
+       for (i=0; i < 8; ++i)
+       {
+               res += *p;
+               printf("%0x ", (int) *(p++));
+       }
+       putchar('\n');
+
+       return res + 1000000;
+}
+
+
diff --git a/mono/tests/pinvoke13.cs b/mono/tests/pinvoke13.cs
new file mode 100644 (file)
index 0000000..0a62838
--- /dev/null
@@ -0,0 +1,40 @@
+using System;
+using System.Runtime.InteropServices;
+
+public class DumpTest
+{
+       /* this should call HexDumpA with ANSI encoded string */
+       [DllImport("libtest.so", CharSet=CharSet.Ansi)]
+       private static extern int HexDump (string data);
+
+       /* this should call HexDump default version with Unicode string */
+       [DllImport("libtest.so", EntryPoint="HexDump", CharSet=CharSet.Unicode)]
+       private static extern int HexDump2(string data);
+
+       /* this should call HexDump1W with unicode encoding */
+       [DllImport("libtest.so", CharSet=CharSet.Unicode)]
+       private static extern int HexDump1(string data);
+
+       public static int Main()
+       {
+               int res;
+               
+               res = HexDump ("First test");
+               Console.WriteLine (res);
+               if (res != 100769)
+                       return 1;
+
+               res = HexDump2 ("First test");
+               Console.WriteLine (res);
+               if (res != 404)
+                       return 2;
+
+               res = HexDump1 ("First test");
+               Console.WriteLine (res);
+               if (res != 1000404)
+                       return 3;
+
+               return 0;               
+       }
+}
+