How to define a global field in ModuleBuilder

I am doing dynamic assemblies with System.Reflection.Emit , and I want to define a module level field that can be obtained using Module.GetField . There are methods in ModuleBuilder for defining global methods, but the only thing I could find was similar to the DefineGlobalField method: DefineInitializedData and DefineUninitializedData , but for them I specify the size (or the initial value from which to determine the size), and not the type, As I can i do this?

+5
source share
1 answer

After some screening of the source code for the reflection.emit classes, I found that global methods are actually written to TypeBuilder , which is hidden behind the ModuleBuilder interface. You really should not have access to it, but if you get it through reflection, any fields (and methods) that you define on it will become global (if you try to define properties or events, no errors will be thrown, but as far as I can judge, they are not actually defined). This is a working solution, but it is obvious that you should not do this, so if someone comes up with the best one, submit it. Meanwhile, here is the code for it:

 var moduleData = myModule.GetType().GetField("m_moduleData", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(myModule); var globalTypeBuilder = (TypeBuilder) moduleData.GetType().GetField("m_globalTypeBuilder", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(moduleData); globalTypeBuilder.DefineField("myGlobalVar", typeof(int), FieldAttributes.Public | FieldAttributes.Static); myModule.CreateGlobalFunctions(); 

Please note: a) that any fields or methods defined in globalTypeBuilder must be static, b) there are no advantages that I can define for defining methods on globalTypeBuilder , but simply using Module.DefineGlobalMethod and c) even if using globalTypeBuilder , you still need to call Module.CreateGlobalFunctions , whether global methods, global fields, or both.

0
source

Source: https://habr.com/ru/post/1276204/


All Articles