mscoree: Factor out common code for calling .NET methods.
This commit is contained in:
parent
88dfdded62
commit
1986e496c7
|
@ -153,23 +153,25 @@ static void RuntimeHost_DeleteDomain(RuntimeHost *This, MonoDomain *domain)
|
||||||
LeaveCriticalSection(&This->lock);
|
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;
|
MonoAssembly *assembly;
|
||||||
MonoImage *image;
|
MonoImage *image;
|
||||||
MonoClass *klass;
|
MonoClass *klass;
|
||||||
MonoMethod *method;
|
MonoMethod *method;
|
||||||
MonoObject *appdomain_object;
|
MonoObject *exc;
|
||||||
IUnknown *unk;
|
static const char *get_hresult = "get_HResult";
|
||||||
|
|
||||||
|
*result = NULL;
|
||||||
|
|
||||||
mono_thread_attach(domain);
|
mono_thread_attach(domain);
|
||||||
|
|
||||||
assembly = mono_domain_assembly_open(domain, "mscorlib");
|
assembly = mono_domain_assembly_open(domain, assemblyname);
|
||||||
if (!assembly)
|
if (!assembly)
|
||||||
{
|
{
|
||||||
ERR("Cannot load mscorlib\n");
|
ERR("Cannot load assembly\n");
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,29 +182,57 @@ static HRESULT RuntimeHost_GetIUnknownForDomain(RuntimeHost *This, MonoDomain *d
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
klass = mono_class_from_name(image, "System", "AppDomain");
|
klass = mono_class_from_name(image, namespace, typename);
|
||||||
if (!klass)
|
if (!klass)
|
||||||
{
|
{
|
||||||
ERR("Couldn't get class from image\n");
|
ERR("Couldn't get class from image\n");
|
||||||
return E_FAIL;
|
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)
|
if (!method)
|
||||||
{
|
{
|
||||||
ERR("Couldn't get method from class\n");
|
ERR("Couldn't get method from class\n");
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
args[0] = NULL;
|
*result = mono_runtime_invoke(method, obj, args, &exc);
|
||||||
appdomain_object = mono_runtime_invoke(method, NULL, args, NULL);
|
if (exc)
|
||||||
if (!appdomain_object)
|
|
||||||
{
|
{
|
||||||
ERR("Couldn't get result pointer\n");
|
HRESULT hr;
|
||||||
return E_FAIL;
|
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))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
|
@ -219,10 +249,7 @@ void RuntimeHost_ExitProcess(RuntimeHost *This, INT exitcode)
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
void *args[2];
|
void *args[2];
|
||||||
MonoDomain *domain;
|
MonoDomain *domain;
|
||||||
MonoAssembly *assembly;
|
MonoObject *dummy;
|
||||||
MonoImage *image;
|
|
||||||
MonoClass *klass;
|
|
||||||
MonoMethod *method;
|
|
||||||
|
|
||||||
hr = RuntimeHost_GetDefaultDomain(This, &domain);
|
hr = RuntimeHost_GetDefaultDomain(This, &domain);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
@ -231,39 +258,10 @@ void RuntimeHost_ExitProcess(RuntimeHost *This, INT exitcode)
|
||||||
return;
|
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[0] = &exitcode;
|
||||||
args[1] = NULL;
|
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");
|
ERR("Process should have exited\n");
|
||||||
}
|
}
|
||||||
|
@ -629,13 +627,8 @@ static HRESULT WINAPI CLRRuntimeHost_ExecuteInDefaultAppDomain(ICLRRuntimeHost*
|
||||||
RuntimeHost *This = impl_from_ICLRRuntimeHost( iface );
|
RuntimeHost *This = impl_from_ICLRRuntimeHost( iface );
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
MonoDomain *domain;
|
MonoDomain *domain;
|
||||||
MonoAssembly *assembly;
|
|
||||||
MonoImage *image;
|
|
||||||
MonoClass *klass;
|
|
||||||
MonoMethod *method;
|
|
||||||
MonoObject *result;
|
MonoObject *result;
|
||||||
MonoString *str;
|
MonoString *str;
|
||||||
void *args[2];
|
|
||||||
char *filenameA = NULL, *classA = NULL, *methodA = NULL;
|
char *filenameA = NULL, *classA = NULL, *methodA = NULL;
|
||||||
char *argsA = NULL, *ns;
|
char *argsA = NULL, *ns;
|
||||||
|
|
||||||
|
@ -643,66 +636,60 @@ static HRESULT WINAPI CLRRuntimeHost_ExecuteInDefaultAppDomain(ICLRRuntimeHost*
|
||||||
debugstr_w(pwzTypeName), debugstr_w(pwzMethodName), debugstr_w(pwzArgument));
|
debugstr_w(pwzTypeName), debugstr_w(pwzMethodName), debugstr_w(pwzArgument));
|
||||||
|
|
||||||
hr = RuntimeHost_GetDefaultDomain(This, &domain);
|
hr = RuntimeHost_GetDefaultDomain(This, &domain);
|
||||||
if(hr != S_OK)
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
ERR("Couldn't get Default Domain\n");
|
mono_thread_attach(domain);
|
||||||
return hr;
|
|
||||||
|
filenameA = WtoA(pwzAssemblyPath);
|
||||||
|
if (!filenameA) hr = E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = E_FAIL;
|
if (SUCCEEDED(hr))
|
||||||
|
|
||||||
mono_thread_attach(domain);
|
|
||||||
|
|
||||||
filenameA = WtoA(pwzAssemblyPath);
|
|
||||||
assembly = mono_domain_assembly_open(domain, filenameA);
|
|
||||||
if (!assembly)
|
|
||||||
{
|
{
|
||||||
ERR("Cannot open assembly %s\n", filenameA);
|
classA = WtoA(pwzTypeName);
|
||||||
goto cleanup;
|
if (!classA) hr = E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
image = mono_assembly_get_image(assembly);
|
if (SUCCEEDED(hr))
|
||||||
if (!image)
|
|
||||||
{
|
{
|
||||||
ERR("Couldn't get assembly image\n");
|
ns = strrchr(classA, '.');
|
||||||
goto cleanup;
|
if (ns)
|
||||||
|
*ns = '\0';
|
||||||
|
else
|
||||||
|
hr = E_INVALIDARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
classA = WtoA(pwzTypeName);
|
if (SUCCEEDED(hr))
|
||||||
ns = strrchr(classA, '.');
|
|
||||||
*ns = '\0';
|
|
||||||
klass = mono_class_from_name(image, classA, ns+1);
|
|
||||||
if (!klass)
|
|
||||||
{
|
{
|
||||||
ERR("Couldn't get class from image\n");
|
methodA = WtoA(pwzMethodName);
|
||||||
goto cleanup;
|
if (!methodA) hr = E_OUTOFMEMORY;
|
||||||
}
|
|
||||||
|
|
||||||
methodA = WtoA(pwzMethodName);
|
|
||||||
method = mono_class_get_method_from_name(klass, methodA, 1);
|
|
||||||
if (!method)
|
|
||||||
{
|
|
||||||
ERR("Couldn't get method from class\n");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The .NET function we are calling has the following declaration
|
/* The .NET function we are calling has the following declaration
|
||||||
* public static int functionName(String param)
|
* public static int functionName(String param)
|
||||||
*/
|
*/
|
||||||
argsA = WtoA(pwzArgument);
|
if (SUCCEEDED(hr))
|
||||||
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
|
|
||||||
{
|
{
|
||||||
*pReturnValue = *(DWORD*)mono_object_unbox(result);
|
argsA = WtoA(pwzArgument);
|
||||||
hr = S_OK;
|
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, filenameA);
|
||||||
HeapFree(GetProcessHeap(), 0, classA);
|
HeapFree(GetProcessHeap(), 0, classA);
|
||||||
HeapFree(GetProcessHeap(), 0, argsA);
|
HeapFree(GetProcessHeap(), 0, argsA);
|
||||||
|
@ -807,60 +794,20 @@ HRESULT RuntimeHost_GetIUnknownForObject(RuntimeHost *This, MonoObject *obj,
|
||||||
IUnknown **ppUnk)
|
IUnknown **ppUnk)
|
||||||
{
|
{
|
||||||
MonoDomain *domain;
|
MonoDomain *domain;
|
||||||
MonoAssembly *assembly;
|
|
||||||
MonoImage *image;
|
|
||||||
MonoClass *klass;
|
|
||||||
MonoMethod *method;
|
|
||||||
MonoObject *result;
|
MonoObject *result;
|
||||||
void *args[2];
|
HRESULT hr;
|
||||||
|
|
||||||
domain = mono_object_get_domain(obj);
|
domain = mono_object_get_domain(obj);
|
||||||
|
|
||||||
assembly = mono_domain_assembly_open(domain, "mscorlib");
|
hr = RuntimeHost_Invoke(This, domain, "mscorlib", "System.Runtime.InteropServices", "Marshal", "GetIUnknownForObject",
|
||||||
if (!assembly)
|
NULL, (void**)&obj, 1, &result);
|
||||||
{
|
|
||||||
ERR("Cannot load mscorlib\n");
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
image = mono_assembly_get_image(assembly);
|
if (SUCCEEDED(hr))
|
||||||
if (!image)
|
*ppUnk = *(IUnknown**)mono_object_unbox(result);
|
||||||
{
|
else
|
||||||
ERR("Couldn't get assembly image\n");
|
*ppUnk = NULL;
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
klass = mono_class_from_name(image, "System.Runtime.InteropServices", "Marshal");
|
return hr;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_utf8_args(int *argc, char ***argv)
|
static void get_utf8_args(int *argc, char ***argv)
|
||||||
|
|
Loading…
Reference in New Issue