我正在尝试为CIL(Microsoft IL(制作一个编译器。在写完IL文件后,我使用ilasm(CIL汇编程序(生成相应的.exe文件。在我尝试添加泛型之后,我在尝试运行可执行文件时遇到以下错误:
Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'fungjprg, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. Signature has bad element type. (Exception from HRESULT: 0x80131247) ---> System.Runtime.InteropServices.COMException: Signature has bad element type. (Exception from HRESULT: 0x80131247)
--- End of inner exception stack trace ---
我真的不明白这是从哪里来的,因为在试图编译泛型类型之前,一切都可以完美地工作。此外,由于我认为我的IL代码很糟糕,我用C#编写了一个简单的通用程序,并使用它生成的IL(使用ILDASM(,并试图运行它,但我得到了完全相同的错误。
C#代码:
class Program
{
static void Main(string[] args)
{
System.Console.WriteLine(new A<int>(3).f());
}
}
class A<X>
{
X val;
public A(X val)
{
this.val = val;
}
public X f()
{
return this.val;
}
}
我的CIL文件:
.assembly extern System.Runtime
{
.publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A)
.ver 4:0:0:0
}
.assembly extern System.Console
{
.publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A)
.ver 4:0:0:0
}
.assembly fungjprg
{
.hash algorithm 0x00008004 // I tried to add/remove this, same result...
.ver 1:0:0:0 // I tried to add/remove this, same result...
}
.class private auto ansi beforefieldinit fungjprg.A`1<X>
extends [System.Runtime]System.Object
{
.method public hidebysig specialname rtspecialname
instance void .ctor(!X val) cil managed
{
// Code size 16 (0x10)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [System.Runtime]System.Object::.ctor()
IL_0006: nop
IL_0007: nop
IL_0008: ldarg.0
IL_0009: ldarg.1
IL_000a: stfld !0 class fungjprg.A`1<!X>::val
IL_000f: ret
}
.method public hidebysig instance !X f() cil managed
{
// Code size 12 (0xc)
.maxstack 1
.locals init (!X V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld !0 class fungjprg.A`1<!X>::val
IL_0007: stloc.0
IL_0008: br.s IL_000a
IL_000a: ldloc.0
IL_000b: ret
}
}
.field private !X val
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 19 (0x13)
.maxstack 8
IL_0000: nop
IL_0001: ldc.i4.3
IL_0002: newobj instance void class fungjprg.A`1<int32>::.ctor(!0)
IL_0007: call instance !0 class fungjprg.A`1<int32>::f()
IL_000c: call void [System.Console]System.Console::WriteLine(int32)
IL_0011: nop
IL_0012: ret
}
ILASM输出:
Microsoft (R) .NET Framework IL Assembler. Version 4.8.3752.0
Copyright (c) Microsoft Corporation. All rights reserved.
Assembling 'compiledprogram.fungj' to EXE --> 'compiledprogram.exe'
Source file is ANSI
Assembled method fungjprg.A`1::.ctor
Assembled method fungjprg.A`1::f
compiledprogram.fungj(54) : warning : Non-static global field, made static
Assembled global method Main
Creating PE file
Emitting classes:
Class 1: fungjprg.A`1
Emitting fields and methods:
Global Fields: 1; Methods: 1;
Class 1 Methods: 2;
Emitting events and properties:
Global
Class 1
Writing PE file
Operation completed successfully
我试图用强名称密钥对IL文件进行签名,但错误仍然存在(唯一的区别是PublicKeyToken不再为空(
根据您的CIL文件,.field private !X val
不是类a的一部分。这很奇怪,因为根据C#代码,它看起来是类a的组成部分。
尝试将.field private !X val
移动到类范围中,类似于
.class private auto ansi beforefieldinit fungjprg.A`1<X>
extends [System.Runtime]System.Object
{
.field private !X val
.method public hidebysig specialname rtspecialname
instance void .ctor(!X val) cil managed
{
// method code..
}
}
编辑:我用修复程序运行了你的CIL文件,它对我有效