+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
}
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);
mspecs [cols [MONO_PARAM_SEQUENCE]]= mono_metadata_parse_marshal_spec (klass->image, tp);
}
}
+
return;
}
}
mono_marshal_get_native_wrapper (MonoMethod *method)
{
MonoMethodSignature *sig, *csig;
+ MonoMethodPInvoke *piinfo;
MonoMethodBuilder *mb;
MonoMarshalSpec **mspecs;
MonoMethod *res;
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);
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]);
pinvoke10.cs \
pinvoke11.cs \
pinvoke12.cs \
+ pinvoke13.cs \
invoke.cs \
invoke2.cs \
reinit.cs \
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;
+}
+
+
--- /dev/null
+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;
+ }
+}
+