Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZoltan Varga <vargaz@gmail.com>2004-09-09 15:22:08 +0400
committerZoltan Varga <vargaz@gmail.com>2004-09-09 15:22:08 +0400
commit6182f42e5557a68f5aab0bbee0b182cf03f70e0e (patch)
treecd62e91c1fc4e0a662b852028d38963b3dcfb0e9
parente1b7e8c457247c6a89c805cf1ce3eb98b8a74d36 (diff)
Merge from HEAD.
svn path=/branches/mono-1-0/mono/; revision=33645
-rw-r--r--mono/metadata/ChangeLog5
-rw-r--r--mono/metadata/loader.c39
-rw-r--r--mono/metadata/reflection.c22
-rw-r--r--mono/metadata/reflection.h1
4 files changed, 54 insertions, 13 deletions
diff --git a/mono/metadata/ChangeLog b/mono/metadata/ChangeLog
index 5912343b15e..290a12448d9 100644
--- a/mono/metadata/ChangeLog
+++ b/mono/metadata/ChangeLog
@@ -1,3 +1,8 @@
+2004-09-09 Zoltan Varga <vargaz@freemail.hu>
+
+ * reflection.h reflection.c loader.c: Allow dynamic construction of
+ pinvoke methods. Fixes #65571.
+
2004-09-08 Lluis Sanchez Gual <lluis@novell.com>
* object.c: In mono_message_invoke, fill the output parameter array after
diff --git a/mono/metadata/loader.c b/mono/metadata/loader.c
index 81f2af3fa7c..5521d6f3299 100644
--- a/mono/metadata/loader.c
+++ b/mono/metadata/loader.c
@@ -580,28 +580,41 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char
g_assert (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL);
- if (exc_class) {
- *exc_class = NULL;
- *exc_arg = NULL;
- }
-
if (method->addr)
return method->addr;
- if (!piinfo->implmap_idx)
- return NULL;
-
- mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
- piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
- import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
- scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
- orig_scope = mono_metadata_string_heap (image, scope_token);
+ if (method->klass->image->dynamic) {
+ MonoReflectionMethodAux *method_aux =
+ mono_g_hash_table_lookup (
+ ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
+ if (!method_aux)
+ return NULL;
+
+ import = method_aux->dllentry;
+ orig_scope = method_aux->dll;
+ }
+ else {
+ if (!piinfo->implmap_idx)
+ return NULL;
+
+ mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
+
+ piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
+ import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
+ scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
+ orig_scope = mono_metadata_string_heap (image, scope_token);
+ }
mono_dllmap_lookup (image, orig_scope, import, &new_scope, &import);
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT,
"DllImport attempting to load: '%s'.", new_scope);
+ if (exc_class) {
+ *exc_class = NULL;
+ *exc_arg = NULL;
+ }
+
#ifndef PLATFORM_WIN32
/*
* If we are P/Invoking a library from System.Windows.Forms, load Wine
diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c
index bf22f1f6d4a..d8335dbdf2f 100644
--- a/mono/metadata/reflection.c
+++ b/mono/metadata/reflection.c
@@ -61,6 +61,9 @@ typedef struct {
MonoMethod *mhandle;
guint32 nrefs;
gpointer *refs;
+ /* for PInvoke */
+ int charset, lasterr, native_cc;
+ MonoString *dll, *dllentry;
} ReflectionMethodBuilder;
const unsigned char table_sizes [64] = {
@@ -1260,6 +1263,14 @@ reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb,
rmb->mhandle = mb->mhandle;
rmb->nrefs = 0;
rmb->refs = NULL;
+
+ if (mb->dll) {
+ rmb->charset = rmb->charset & 0xf;
+ rmb->lasterr = rmb->charset & 0x40;
+ rmb->native_cc = rmb->native_cc;
+ rmb->dllentry = mb->dllentry;
+ rmb->dll = mb->dll;
+ }
}
static void
@@ -7016,6 +7027,17 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
} else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
/* TODO */
m->signature->pinvoke = 1;
+
+ method_aux = g_new0 (MonoReflectionMethodAux, 1);
+
+ method_aux->dllentry = g_strdup (mono_string_to_utf8 (rmb->dllentry));
+ method_aux->dll = g_strdup (mono_string_to_utf8 (rmb->dll));
+
+ ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 1) | rmb->lasterr;
+
+ if (klass->image->dynamic)
+ mono_g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
+
return m;
} else if (!m->klass->dummy &&
!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
diff --git a/mono/metadata/reflection.h b/mono/metadata/reflection.h
index e44243f3d66..f365047c3b6 100644
--- a/mono/metadata/reflection.h
+++ b/mono/metadata/reflection.h
@@ -34,6 +34,7 @@ typedef struct {
char **param_names;
MonoMarshalSpec **param_marshall;
MonoCustomAttrInfo **param_cattr;
+ char *dllentry, *dll;
} MonoReflectionMethodAux;
int mono_reflection_parse_type (char *name, MonoTypeNameParse *info);