Things to remember when creating delegates and doing LCG...
In my AcquiringObjectDataSource articles part three I promised to show what things look like using the DynamicCall library I've previously posted. In doing that, I've had to make the DynamicCall stuff work with static methods. Previously I had inserted some code to start handling statics deep inside the Build methods, but I've certainly never gotten to the point of using them. Sorry to anyone that tried, I should have documented that code as not-yet working.
Anyway, last night I worked into the wee hours of the morning getting everything hooked up for static methods. In the process I learned some things that I thought I would dump now. In an upcoming post, I'll talk about the changes to the DynamicCall library, but for now: 
- When you create a delegate for a staticmethod, the delegate signature should not include a "this" reference. Duh. This manifests itself in the error message below when callingCreateDelegate. This happens because the delegate definition expects a "this" pointer as the first method argument, but the generatedDynamicMethoddoesn't have one. This spawned a whole new set ofStaticProcandStaticFuncdelegate definitions.ArgumentException: Error binding to target method 
- If you get the delegate definition correct, but don't generate the right code, it'll hurl at JIT with the message below. Note that the generation of the LCG DynamicMethodis fine, the delegate binding is fine. The JIT of the first caller to that delegate is where things will pop. This is often very in the runtime, which is bad.System.InvalidProgramException: Common Language Runtime detected an invalid program. 
- Not strictly related to staticmethod supprt, but I rediscovered that you can't access private members of a class unless theDynamicMethodwas properly bound to that class. This resulted in me still having to know the class of thestaticmethod, even though there's no "this" pointer to deal with.
- Ruthless refactoring makes things much easier. Doing this work on the DynamicCalllibrary has really cleaned things up, I'll give more detail in a later post.
As it stands now binding to a static method now looks like this: 
StaticProc<ObjectDataSourceView, ParameterCollection, IDictionary, IDictionary> s_MergeDictionaries =
    DynamicProcedure<ObjectDataSourceView, ParameterCollection, IDictionary, IDictionary>.Static.Initialize("MergeDictionaries", CreateParameterList.Auto);
    Dynamic<ObjectDataSourceView>.Static.Procedure.Explicit<ParameterCollection, IDictionary, IDictionary>.CreateDelegate("MergeDictionaries", CreateParameterList.Auto);While this is really clear (I think), it is very verbose. The new C# 3.0 "var" feature will will make this much more readable:
var s_MergeDictionaries =
    DynamicProcedure<ObjectDataSourceView, ParameterCollection, IDictionary, IDictionary>.Static.Initialize("MergeDictionaries", CreateParameterList.Auto);
    Dynamic<ObjectDataSourceView>.Static.Procedure.Explicit<ParameterCollection, IDictionary, IDictionary>.CreateDelegate("MergeDictionaries", CreateParameterList.Auto);UPDATE (27-July-2007 15:32): New syntax based on the latest round of refactorings on the DynamicCallDynamic<> class.
 
 
 Posts
Posts
 
 
No comments:
Post a Comment