如何在ModuleBuilder中定义全局字段

时间:2018-03-31 23:34:49

标签: c# reflection.emit

我正在使用System.Reflection.Emit制作动态程序集,我想定义一个模块级字段,即可以使用Module.GetField检索的字段。 ModuleBuilder中有一些方法可以定义全局方法,但我唯一能找到的方法就像" DefineGlobalField"方法是DefineInitializedDataDefineUninitializedData,但是对于这些,我指定一个大小(或初始值,可以从中推断出大小)而不是类型。我怎么能这样做?

1 个答案:

答案 0 :(得分:1)

在对reflection.emit类的源代码进行一些筛选之后,我发现全局方法实际上被写入隐藏在TypeBuilder接口后面的ModuleBuilder。你真的不应该能够访问它,但如果你通过反射得到它,你在其上定义的任何字段(和方法)将变为模块全局(如果你试图定义属性或事件,没有错误将被抛出,但据我所知,他们实际上没有被定义)。这是一个有效的解决方案,但显然你不应该这样做,所以如果有人想出更好的解决方案,请发布。与此同时,这是代码:

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();

请注意a)globalTypeBuilder上定义的任何字段或方法必须是静态的,b)我在globalTypeBuilder上定义方法没有优势,而只是使用Module.DefineGlobalMethod ,c)即使使用globalTypeBuilder,您仍然需要调用Module.CreateGlobalFunctions,无论是全局方法,全局字段还是两者。