[2/2] mscoree: Factor out common code for calling .NET methods.
Vincent Povirk
madewokherd at gmail.com
Mon Aug 18 11:33:30 CDT 2014
-------------- next part --------------
From 0b97eb7dbf76ec8fed490316e1212765bf948347 Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Wed, 13 Aug 2014 17:05:44 -0500
Subject: [PATCH 2/2] mscoree: Factor out common code for calling .NET methods.
---
dlls/mscoree/corruntimehost.c | 235 ++++++++++++++++--------------------------
1 file changed, 91 insertions(+), 144 deletions(-)
diff --git a/dlls/mscoree/corruntimehost.c b/dlls/mscoree/corruntimehost.c
index b44fb6a..ce73134 100644
--- a/dlls/mscoree/corruntimehost.c
+++ b/dlls/mscoree/corruntimehost.c
@@ -153,23 +153,25 @@ static void RuntimeHost_DeleteDomain(RuntimeHost *This, MonoDomain *domain)
LeaveCriticalSection(&This->lock);
}
-static HRESULT RuntimeHost_GetIUnknownForDomain(RuntimeHost *This, MonoDomain *domain, IUnknown **punk)
+static HRESULT RuntimeHost_Invoke(RuntimeHost *This, MonoDomain *domain,
+ const char *assemblyname, const char *namespace, const char *typename, const char *methodname,
+ MonoObject *obj, void **args, int arg_count, MonoObject **result)
{
- HRESULT hr;
- void *args[1];
MonoAssembly *assembly;
MonoImage *image;
MonoClass *klass;
MonoMethod *method;
- MonoObject *appdomain_object;
- IUnknown *unk;
+ MonoObject *exc;
+ static const char *get_hresult = "get_HResult";
+
+ *result = NULL;
mono_thread_attach(domain);
- assembly = mono_domain_assembly_open(domain, "mscorlib");
+ assembly = mono_domain_assembly_open(domain, assemblyname);
if (!assembly)
{
- ERR("Cannot load mscorlib\n");
+ ERR("Cannot load assembly\n");
return E_FAIL;
}
@@ -180,29 +182,57 @@ static HRESULT RuntimeHost_GetIUnknownForDomain(RuntimeHost *This, MonoDomain *d
return E_FAIL;
}
- klass = mono_class_from_name(image, "System", "AppDomain");
+ klass = mono_class_from_name(image, namespace, typename);
if (!klass)
{
ERR("Couldn't get class from image\n");
return E_FAIL;
}
- method = mono_class_get_method_from_name(klass, "get_CurrentDomain", 0);
+ method = mono_class_get_method_from_name(klass, methodname, arg_count);
if (!method)
{
ERR("Couldn't get method from class\n");
return E_FAIL;
}
- args[0] = NULL;
- appdomain_object = mono_runtime_invoke(method, NULL, args, NULL);
- if (!appdomain_object)
+ *result = mono_runtime_invoke(method, obj, args, &exc);
+ if (exc)
{
- ERR("Couldn't get result pointer\n");
- return E_FAIL;
+ HRESULT hr;
+ MonoObject *hr_object;
+
+ if (methodname != get_hresult)
+ {
+ /* Map the exception to an HRESULT. */
+ hr = RuntimeHost_Invoke(This, domain, "mscorlib", "System", "Exception", get_hresult,
+ exc, NULL, 0, &hr_object);
+ if (SUCCEEDED(hr))
+ hr = *(HRESULT*)mono_object_unbox(hr_object);
+ if (SUCCEEDED(hr))
+ hr = E_FAIL;
+ }
+ else
+ hr = E_FAIL;
+ ERR("Method %s.%s raised an exception, hr=%x\n", namespace, typename, hr);
+ *result = NULL;
+ return hr;
}
- hr = RuntimeHost_GetIUnknownForObject(This, appdomain_object, &unk);
+ return S_OK;
+}
+
+static HRESULT RuntimeHost_GetIUnknownForDomain(RuntimeHost *This, MonoDomain *domain, IUnknown **punk)
+{
+ HRESULT hr;
+ MonoObject *appdomain_object;
+ IUnknown *unk;
+
+ hr = RuntimeHost_Invoke(This, domain, "mscorlib", "System", "AppDomain", "get_CurrentDomain",
+ NULL, NULL, 0, &appdomain_object);
+
+ if (SUCCEEDED(hr))
+ hr = RuntimeHost_GetIUnknownForObject(This, appdomain_object, &unk);
if (SUCCEEDED(hr))
{
@@ -219,10 +249,7 @@ void RuntimeHost_ExitProcess(RuntimeHost *This, INT exitcode)
HRESULT hr;
void *args[2];
MonoDomain *domain;
- MonoAssembly *assembly;
- MonoImage *image;
- MonoClass *klass;
- MonoMethod *method;
+ MonoObject *dummy;
hr = RuntimeHost_GetDefaultDomain(This, &domain);
if (FAILED(hr))
@@ -231,39 +258,10 @@ void RuntimeHost_ExitProcess(RuntimeHost *This, INT exitcode)
return;
}
- mono_thread_attach(domain);
-
- assembly = mono_domain_assembly_open(domain, "mscorlib");
- if (!assembly)
- {
- ERR("Cannot load mscorlib\n");
- return;
- }
-
- image = mono_assembly_get_image(assembly);
- if (!image)
- {
- ERR("Couldn't get assembly image\n");
- return;
- }
-
- klass = mono_class_from_name(image, "System", "Environment");
- if (!klass)
- {
- ERR("Couldn't get class from image\n");
- return;
- }
-
- method = mono_class_get_method_from_name(klass, "Exit", 1);
- if (!method)
- {
- ERR("Couldn't get method from class\n");
- return;
- }
-
args[0] = &exitcode;
args[1] = NULL;
- mono_runtime_invoke(method, NULL, args, NULL);
+ RuntimeHost_Invoke(This, domain, "mscorlib", "System", "Environment", "Exit",
+ NULL, args, 1, &dummy);
ERR("Process should have exited\n");
}
@@ -629,13 +627,8 @@ static HRESULT WINAPI CLRRuntimeHost_ExecuteInDefaultAppDomain(ICLRRuntimeHost*
RuntimeHost *This = impl_from_ICLRRuntimeHost( iface );
HRESULT hr;
MonoDomain *domain;
- MonoAssembly *assembly;
- MonoImage *image;
- MonoClass *klass;
- MonoMethod *method;
MonoObject *result;
MonoString *str;
- void *args[2];
char *filenameA = NULL, *classA = NULL, *methodA = NULL;
char *argsA = NULL, *ns;
@@ -643,66 +636,60 @@ static HRESULT WINAPI CLRRuntimeHost_ExecuteInDefaultAppDomain(ICLRRuntimeHost*
debugstr_w(pwzTypeName), debugstr_w(pwzMethodName), debugstr_w(pwzArgument));
hr = RuntimeHost_GetDefaultDomain(This, &domain);
- if(hr != S_OK)
- {
- ERR("Couldn't get Default Domain\n");
- return hr;
- }
- hr = E_FAIL;
-
- mono_thread_attach(domain);
-
- filenameA = WtoA(pwzAssemblyPath);
- assembly = mono_domain_assembly_open(domain, filenameA);
- if (!assembly)
+ if (SUCCEEDED(hr))
{
- ERR("Cannot open assembly %s\n", filenameA);
- goto cleanup;
+ mono_thread_attach(domain);
+
+ filenameA = WtoA(pwzAssemblyPath);
+ if (!filenameA) hr = E_OUTOFMEMORY;
}
- image = mono_assembly_get_image(assembly);
- if (!image)
+ if (SUCCEEDED(hr))
{
- ERR("Couldn't get assembly image\n");
- goto cleanup;
+ classA = WtoA(pwzTypeName);
+ if (!classA) hr = E_OUTOFMEMORY;
}
- classA = WtoA(pwzTypeName);
- ns = strrchr(classA, '.');
- *ns = '\0';
- klass = mono_class_from_name(image, classA, ns+1);
- if (!klass)
+ if (SUCCEEDED(hr))
{
- ERR("Couldn't get class from image\n");
- goto cleanup;
+ ns = strrchr(classA, '.');
+ if (ns)
+ *ns = '\0';
+ else
+ hr = E_INVALIDARG;
}
- methodA = WtoA(pwzMethodName);
- method = mono_class_get_method_from_name(klass, methodA, 1);
- if (!method)
+ if (SUCCEEDED(hr))
{
- ERR("Couldn't get method from class\n");
- goto cleanup;
+ methodA = WtoA(pwzMethodName);
+ if (!methodA) hr = E_OUTOFMEMORY;
}
/* The .NET function we are calling has the following declaration
* public static int functionName(String param)
*/
- argsA = WtoA(pwzArgument);
- str = mono_string_new(domain, argsA);
- args[0] = str;
- args[1] = NULL;
- result = mono_runtime_invoke(method, NULL, args, NULL);
- if (!result)
- ERR("Couldn't get result pointer\n");
- else
+ if (SUCCEEDED(hr))
{
- *pReturnValue = *(DWORD*)mono_object_unbox(result);
- hr = S_OK;
+ argsA = WtoA(pwzArgument);
+ if (!argsA) hr = E_OUTOFMEMORY;
}
-cleanup:
+ if (SUCCEEDED(hr))
+ {
+ str = mono_string_new(domain, argsA);
+ if (!str) hr = E_OUTOFMEMORY;
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = RuntimeHost_Invoke(This, domain, filenameA, classA, ns+1, methodA,
+ NULL, (void**)&str, 1, &result);
+ }
+
+ if (SUCCEEDED(hr))
+ *pReturnValue = *(DWORD*)mono_object_unbox(result);
+
HeapFree(GetProcessHeap(), 0, filenameA);
HeapFree(GetProcessHeap(), 0, classA);
HeapFree(GetProcessHeap(), 0, argsA);
@@ -807,60 +794,20 @@ HRESULT RuntimeHost_GetIUnknownForObject(RuntimeHost *This, MonoObject *obj,
IUnknown **ppUnk)
{
MonoDomain *domain;
- MonoAssembly *assembly;
- MonoImage *image;
- MonoClass *klass;
- MonoMethod *method;
MonoObject *result;
- void *args[2];
+ HRESULT hr;
domain = mono_object_get_domain(obj);
- assembly = mono_domain_assembly_open(domain, "mscorlib");
- if (!assembly)
- {
- ERR("Cannot load mscorlib\n");
- return E_FAIL;
- }
-
- image = mono_assembly_get_image(assembly);
- if (!image)
- {
- ERR("Couldn't get assembly image\n");
- return E_FAIL;
- }
+ hr = RuntimeHost_Invoke(This, domain, "mscorlib", "System.Runtime.InteropServices", "Marshal", "GetIUnknownForObject",
+ NULL, (void**)&obj, 1, &result);
- klass = mono_class_from_name(image, "System.Runtime.InteropServices", "Marshal");
- if (!klass)
- {
- ERR("Couldn't get class from image\n");
- return E_FAIL;
- }
-
- method = mono_class_get_method_from_name(klass, "GetIUnknownForObject", 1);
- if (!method)
- {
- ERR("Couldn't get method from class\n");
- return E_FAIL;
- }
-
- args[0] = obj;
- args[1] = NULL;
- result = mono_runtime_invoke(method, NULL, args, NULL);
- if (!result)
- {
- ERR("Couldn't get result pointer\n");
- return E_FAIL;
- }
-
- *ppUnk = *(IUnknown**)mono_object_unbox(result);
- if (!*ppUnk)
- {
- ERR("GetIUnknownForObject returned 0\n");
- return E_FAIL;
- }
+ if (SUCCEEDED(hr))
+ *ppUnk = *(IUnknown**)mono_object_unbox(result);
+ else
+ *ppUnk = NULL;
- return S_OK;
+ return hr;
}
static void get_utf8_args(int *argc, char ***argv)
--
1.8.3.2
More information about the wine-patches
mailing list