I'm making dynamic assemblies with System.Reflection.Emit
, and I want to define a module-level field, the kind that can be retrieved with Module.GetField
. There are methods in ModuleBuilder
to define global methods, but the only thing I could find that looked like a "DefineGlobalField
" method are DefineInitializedData
and DefineUninitializedData
, but for these I specify a size (or initial value, from which the size can be inferred) rather than a type. How can I do this?
After some sifting through the source code of the reflection.emit
classes, I discovered that global methods are actually written to a TypeBuilder
hiding behind the ModuleBuilder
interface. You're really not supposed to be able to access it, but if you get ahold of it via reflection, any fields (and methods) you define on it will become module-global (if you try to define properties or events, no errors will be thrown, but as far as I can tell they don't actually get defined). This is a working solution, but it's obvious you're not supposed to do it, so if anyone comes up with a better one, please post it. In the meantime, here's 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();
Note a) that any fields or methods defined on globalTypeBuilder
must be static, b) that there's no advantage that I can tell of defining methods on globalTypeBuilder
rather that just using Module.DefineGlobalMethod
, and c) even when using globalTypeBuilder
you still need to call Module.CreateGlobalFunctions
, whether for global methods, global fields, or both.
© 2022 - 2024 — McMap. All rights reserved.
GetField
with no matchingDefineField
etc); I love this question! That said; using a static type (TypeBuilder) with static fields there might be a pragmatic workaround – Burushaski