BadImageFormatException with Reflection.Emit

  • Thread starter Thread starter Hermann Scheibe
  • Start date Start date
H

Hermann Scheibe

Hi NG,

How can i find what is wrong with my emit code C#?

Scenario:
We have C# class library(DEF_I.dll) with interface definitions:

pulbic interface I
{
public int ZIPCode { get;set;}
...
..
void SomeMethod();
}
99% of all interface properties are very simple:
get-Method returns value from class field
set-Method store value in the class field and call base class setDirty()
method

Also a class library(BASE.dll) with base class BASE defined.
class BASE
{
void setDirty();
}

My idea is to generate and save a Emit.dll with class EMIT_I where all 99%
simple properties
are implemented and all the methods simple throws NotImplementedException().

class EMIT_I : BASE,I
{
private int m_ZIPCode;
int I.ZIPCode { get{ return m_ZIPCode;} set{ m_ZIPCode=value;
setDirty();} }
void I.SomeMethod() { throw new System.NotImplementedException(); }
}

After Emit.dll is emitted we can create the end implementation class IMPL_I
with in IMPL.dll
derived from EMIT_I:

interface I_Impl_Internal : I
{
void SomeInternalMethod();
}

class IMPL : EMIT_I,I_Impl_Internal
{

new I.SomeMethod() { SomeInternalMethod(); }
public void SomeInternalMethod() { /* real implementation here* / }
}

AFAIK at the time as the c# compiler does compile IMPL.dll it should
load and bind Emit.dll.

In my real program the compiler does compile the end dll without errors,
but at the runtime a BadImageFormatException is throwed if i try
to create a IMPL instance.

GREAT! The C# compiler can compile und link Bad Images!?!?!

At the problem research, i have create C# source for emitted piece
und compile it to toBeEmit.dll. After that we can verify emit.dll and
ToBeEmit.dll with help of ILDASM-Tool.

The only difference i have found is the "instance" attribute on all the
properties from toBeEmit.dll.
Emit.dll does't have this attribute:

Emit.dll.il:
..property int32 DEF_I.I.ZIPCode ()
{
.get instance ...
.set instance ...
}

toBeEmit.dll
..property instance int32 DEF_I.I.ZIPCode ()
{
.set instance ...
.get instance ...
}

VS IDE Object browser does't show the I.ZIPCode property for emitted version
only for compiled.

Has anybody a idea to find what is wrong with my code[1]

Attached:
[1]//a code-snip snip from Emit-Code:

const MethodAttributes PropertyImplMethodAttributes=
MethodAttributes.Private
| MethodAttributes.HideBySig
| MethodAttributes.NewSlot
| MethodAttributes.SpecialName
| MethodAttributes.Virtual
| MethodAttributes.Final ;

void BuildDataProp(PropertyInfo pi, TypeBuilder tb,...
{
FieldBuilder fb=null;
if(IsPropTypeSupported(pi.PropertyType))
fb=tb.DefineField(pi.Name,pi.PropertyType,FieldAttributes.Public);
string strPfx =pi.ReflectedType.FullName+".";
PropertyBuilder pb=tb.DefineProperty(
strPfx + pi.Name
, PropertyAttributes.HasDefault
, pi.PropertyType
, new Type[0]{ });
if(pi.CanRead)
{
MethodInfo mi=pi.GetGetMethod();
MethodBuilder mb =tb.DefineMethod(
strPfx+mi.Name
, PropertyImplMethodAttributes
, mi.ReturnType
, new Type[0]);
ILGenerator ilg = mb.GetILGenerator();
if(fb!=null)
{
ilg.Emit(OpCodes.Ldarg_0); //this reference on opstack
ilg.Emit(OpCodes.Ldfld,fb); // load data
ilg.Emit(OpCodes.Ret);
}
else
ImplNotImplException(ilg);
pb.SetGetMethod(mb);
tb.DefineMethodOverride(mb,mi);
}
 
Back
Top