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