Return values get lost with Reflection.Emit

M

Matthias Klöpper

Hi there,
I'm currently trying to call some API-Functions via Reflection.Emit since I
need to bind to different dlls based on user input. The dynamic creation of
the required PInvoke-Methods works just fine and when invoked the functions
are executed perfectly well. The only problem is that I seem to be unable to
get back any return values. To simplify the whole case I created a
test-setup that binds to user32.dll, dynamically creates a PInvokeMethod to
call the MessageBox function and invokes that function. Same effect ... the
return value always is 0. Quite impossible to detect which button was
clicked this way :-(
The example provided in the MSDN is not really helpful since it simply
ignores the return value since they a simple OkOnly-MessageBox in contrast
to my Cancel/Retry/Ignore-box.
Anybody out there who can reproduce my scenario or can point me to where I
screwed up? Any help would be greatly appreciated.

Greeting,
Matti

public class Manager
{
AssemblyBuilder assembly;

public Manager()
{
assembly = CreateDLLAccess();
TestApiCall(assembly);
}

private AssemblyBuilder CreateDLLAccess()
{
AppDomain currentDomain;
AssemblyName name;
MethodBuilder method=null;
AssemblyBuilder assembly;
ModuleBuilder module;

// Get the current application domain for the current thread.
currentDomain = AppDomain.CurrentDomain;
name = new AssemblyName();
name.Name = "TEST";

// Define a dynamic assembly in the 'currentDomain'.
assembly = currentDomain.DefineDynamicAssembly(name,
AssemblyBuilderAccess.Run);

// Define a dynamic module in "TEST" assembly.
module = assembly.DefineDynamicModule("ApiWrapper");

// Define a PInvoke method giving the name of the entrypoint in the
dll.
Type[] myType = new Type[] {typeof(int), typeof(string),
typeof(string), typeof(int)};
method = module.DefinePInvokeMethod("MsgBox", "user32.dll",
"MessageBox", MethodAttributes.Public | MethodAttributes.Static |
MethodAttributes.PinvokeImpl, CallingConventions.Standard, typeof(int),
myType,CallingConvention.Winapi, CharSet.Auto);
module.CreateGlobalFunctions();

return assembly;
}

private void TestApiCall(AssemblyBuilder assembly)
{
Module module = assembly.GetModule("ApiWrapper");
MethodInfo method;
method = module.GetMethod("MsgBox");
object[] args = new object[] {(int) 0, "a", "b", (int) 0x2};
int i = (int) method.Invoke(null, args);
}
}

Whatever I try (fiddling around with Attributes, CallingConventions,
dynamically creating a type for the PInvokeMethod and substituting
MethodInfo.Invoke() with Type.InvokeMethod() or Type.InvokeMember()) i will
always be 0 :-(
 
M

Matthias Klöpper

Hi again,
Mattias Sögren over at framework.interop just posted the solution which
works absolutely perfect:
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top