I try to generate the following code, where G<T> is defined in an
external dll :
public class Test
{
public static void Check<U>()
{
U f = G<U>.F; >> code to generate!
}
}
Here is my code, but its fails to execute.
I think that the problem is to be able to define a IGenericContext
with the current MethodDefinition Check<U>, and a specific
TypeReference (in my code, the typeContext variable). But is it
sufficient to resolve all importation cases ?
assembly1.dll :
public class G<T>
{
public static T F;
}
Test.exe :
public class Test
{
public static void Main() {
// Create the AssemblyDefinition
AssemblyDefinition a = AssemblyDefinition.CreateAssembly(new
AssemblyNameDefinition("output.dll", new Version()), "TestModule",
ModuleKind.Dll);
/*
// Create the G<T> Type
TypeDefinition GOfT;
a.MainModule.Types.Add(GOfT =
new TypeDefinition(null, "G", TypeAttributes.Public |
TypeAttributes.Class, a.MainModule.Import(typeof(object))));
GenericParameter T = new GenericParameter("T", GOfT);
GOfT.GenericParameters.Add(T);
// Create the G<T>.F static Field
FieldDefinition FinGofT;
GOfT.Fields.Add(FinGofT = new FieldDefinition("F",
FieldAttributes.Public | FieldAttributes.Static, T));
*/
AssemblyDefinition aref =
AssemblyDefinition.ReadAssembly("assembly1.dll");
// Get the G<T> type
TypeDefinition GOfT;
GOfT = aref.MainModule.GetType("G`1");
// Get the G<T>.F static Field
FieldDefinition FinGofT;
FinGofT = GOfT.Fields[0];
// Create the Test Type
TypeDefinition Test;
a.MainModule.Types.Add(Test =
new TypeDefinition(null, "Test", TypeAttributes.Public |
TypeAttributes.Class, a.MainModule.Import(typeof(object))));
// Create the Test.Check<U> Method
MethodDefinition CheckOfU;
Test.Methods.Add(CheckOfU = new MethodDefinition("Check",
MethodAttributes.Public | MethodAttributes.Static,
a.MainModule.Import(typeof(void))));
GenericParameter U = new GenericParameter("U", CheckOfU);
CheckOfU.GenericParameters.Add(U);
// Get the G<U> type reference
GenericInstanceType GofU = new GenericInstanceType(GOfT);
GofU.GenericArguments.Add(U);
TypeReference typeContext = a.MainModule.Import(GofU,
CheckOfU);
// Get the G<U>.F static Field
FieldReference fInGofU = new FieldReference("F",
FinGofT.FieldType)
{
DeclaringType = GofU
};
// Defines the instructions
CheckOfU.Body.Variables.Add(new VariableDefinition("f",
a.MainModule.Import(typeof(int))));
CheckOfU.Body.Instructions.Add(Instruction.Create(OpCodes.Ldsfld,
a.MainModule.Import(fInGofU, CheckOfU))); // this line fails!!!
CheckOfU.Body.Instructions.Add(Instruction.Create(OpCodes.Stloc_0));
CheckOfU.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
a.Write("output.dll");
// Check the assembly
SR.Assembly.LoadFrom("output.dll").GetType("Test").GetMethod("Main",
SR.BindingFlags.Public | SR.BindingFlags.Static).Invoke(null, null);
}
}
I have included the Assembly1.7z file that contains the sample
solution for VS 2008.
Thanks a lot for your help.
Regis
--
--
mono-cecil