views:

44

answers:

1

Can anyone tell me what's wrong with my IL code here?

IL_0000: nop        
IL_0001: ldarg.1    
IL_0002: isinst     MyXmlWriter
IL_0007: stloc.0    
IL_0008: ldloc.0    
IL_0009: ldarg.2    
IL_000a: ldind.ref  
IL_000b: unbox.any  TestEnum
IL_0010: ldfld      Int64 value__/FastSerializer.TestEnum
IL_0015: callvirt   Void WriteValue(Int64)/System.Xml.XmlWriter
IL_001a: nop        
IL_001b: ret       

I'm going crazy here, since I've written a test app which does the same thing as above, but in C#, and in reflector the IL code from that looks just like my DynamicMethod's IL code above (except my test C# app uses a TestStruct with a public field instead of the private value field on the enum above, but I have skipVisibility set to true)...

I get a NullReferenceException.

My DynamicMethod's signature is:

public delegate void DynamicWrite(IMyXmlWriter writer, ref object value, MyContract contract);

I generate the method like this:

List<Type> parameterTypes = new List<Type> { 
   typeof(DMBuilder), 
   typeof(IDynamicSerializationWriter), 
   typeof(object).MakeByRefType(), 
   typeof(MyContract) 
}; 
DynamicMethod dm = new DynamicMethod(string.Format(
  "Write_{0}", 
  contract.TypeName), 
  typeof(void), 
  parameterTypes.ToArray(), 
  typeof(DMBuilder), 
  true
);

var d = dm.CreateDelegate(typeof(DynamicWrite), this);
d(x,y); 

And I'm definitely not passing in anything null.

Thanks in advance!

+1  A: 

Forced to take a guess, I'd gamble at you emitting a static method but used an instance method in your C# code. There's definitely a "this" argument (arg.0) but it is never used. Declare it static, compile and disassemble again.

Hans Passant
I am indeed using it as a DynamicMethod on an instance, but I don't think I'm emitting it as static:List<Type> parameterTypes = new List<Type> { typeof(DMBuilder), typeof(IDynamicSerializationWriter), typeof(object).MakeByRefType(), typeof(MyContract) };DynamicMethod dm = new DynamicMethod(string.Format("Write_{0}", contract.TypeName), typeof(void), parameterTypes.ToArray(), typeof(DMBuilder), true);Is that incorrect?
Jeff
@Jeff: that's a static method. It explains your problem, your code is using the wrong arguments.
Hans Passant
Sorry, I guess I'm not fully understanding. I should have included the next line: var d = dm.CreateDelegate(typeof(DynamicWrite), this) Then I invoke like: d(x,y); What should I be doing differently? Thanks.
Jeff
What is the type of "this" you are passing to CreateDelegate? You didn't declare it as an argument to the method. Don't forget: instance methods have a hidden extra 1st argument that passes the object reference.
Hans Passant
This is a DMBuilder instance, the first argument in my List<Type> above that I pass in as type parameters for the DynamicMethod, the delegate signature itself doesn't have this first parameter (since it's hidden).
Jeff
@Jeff: I edited your post, couldn't read it properly in the comments. The delegate call is not correct, please fix it.
Hans Passant