sanikumbh
December 22nd, 2011, 03:50 PM
Hi,
I have bumped into an issue while dynamically generating the IL code that involves multi-dimensional arrays. It can be best demonstrated by following code:
*****************************
using System;
using System.Reflection;
using System.Reflection.Emit;
public interface ITest
{
void Test(double[,] d);
}
class Test
{
static void Main()
{
string name = "TestAssembly";
AssemblyName asmName = new AssemblyName(name);
AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(
asmName, AssemblyBuilderAccess.RunAndSave);
ModuleBuilder mb = ab.DefineDynamicModule(name, name + ".dll");
TypeBuilder tb =
mb.DefineType("TestImpl", TypeAttributes.Public, typeof(System.Object));
tb.AddInterfaceImplementation(typeof(ITest));
MethodInfo mInfo = typeof(ITest).GetMethod("Test");
ParameterInfo[] pInfo = mInfo.GetParameters();
Type paramType = pInfo[0].ParameterType;
MethodBuilder mbIM = tb.DefineMethod("Test",
MethodAttributes.Public | MethodAttributes.Virtual,
null,
new Type[] { paramType });
ILGenerator il = mbIM.GetILGenerator();
il.Emit(OpCodes.Ldstr, "Test method was called");
il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine",
new Type[] { typeof(string) }));
il.Emit(OpCodes.Ret);
Type tc = tb.CreateType();
Object test = Activator.CreateInstance(tc);
MethodInfo mi = tc.GetMethod("Test");
mi.Invoke(test, new object[] { new double[,]{{}} });
Console.ReadLine();
}
}
*****************************
When compile and run this code, I get a TypeLoadException with following message:
{"Method 'Test' in type 'TestImpl' from assembly 'TestAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.":"TestImpl"}
The problem seems to be the type of input to the "Test" method. It only fails if the input type of "Test" is a multi-dimensional array. It works fine for scalars, 1-D arrays or even jagged arrays. E.g. It works fine if Test is changed to something like:
void Test(double[] d);
and corresponding change in the mi.Invoke:
mi.Invoke(test, new object[] { new double[]{ });
I am using Windows 7(64-bit) and .NET Framework 3.5.
Any help would be appreciated,
Thanks
I have bumped into an issue while dynamically generating the IL code that involves multi-dimensional arrays. It can be best demonstrated by following code:
*****************************
using System;
using System.Reflection;
using System.Reflection.Emit;
public interface ITest
{
void Test(double[,] d);
}
class Test
{
static void Main()
{
string name = "TestAssembly";
AssemblyName asmName = new AssemblyName(name);
AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(
asmName, AssemblyBuilderAccess.RunAndSave);
ModuleBuilder mb = ab.DefineDynamicModule(name, name + ".dll");
TypeBuilder tb =
mb.DefineType("TestImpl", TypeAttributes.Public, typeof(System.Object));
tb.AddInterfaceImplementation(typeof(ITest));
MethodInfo mInfo = typeof(ITest).GetMethod("Test");
ParameterInfo[] pInfo = mInfo.GetParameters();
Type paramType = pInfo[0].ParameterType;
MethodBuilder mbIM = tb.DefineMethod("Test",
MethodAttributes.Public | MethodAttributes.Virtual,
null,
new Type[] { paramType });
ILGenerator il = mbIM.GetILGenerator();
il.Emit(OpCodes.Ldstr, "Test method was called");
il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine",
new Type[] { typeof(string) }));
il.Emit(OpCodes.Ret);
Type tc = tb.CreateType();
Object test = Activator.CreateInstance(tc);
MethodInfo mi = tc.GetMethod("Test");
mi.Invoke(test, new object[] { new double[,]{{}} });
Console.ReadLine();
}
}
*****************************
When compile and run this code, I get a TypeLoadException with following message:
{"Method 'Test' in type 'TestImpl' from assembly 'TestAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.":"TestImpl"}
The problem seems to be the type of input to the "Test" method. It only fails if the input type of "Test" is a multi-dimensional array. It works fine for scalars, 1-D arrays or even jagged arrays. E.g. It works fine if Test is changed to something like:
void Test(double[] d);
and corresponding change in the mi.Invoke:
mi.Invoke(test, new object[] { new double[]{ });
I am using Windows 7(64-bit) and .NET Framework 3.5.
Any help would be appreciated,
Thanks