dnLib-Generated Assembly - typeeloadeexception在运行时抛出



我正在使用dnLib从我正在编写的自定义语言动态生成MSIL程序集,名为CSASM:

string absolute = Path.Combine(Directory.GetCurrentDirectory(), forceOutput ?? $"{asmName}.exe");
ModuleDefUser mod = new ModuleDefUser(asmName, Guid.NewGuid(), new AssemblyRefUser(new AssemblyNameInfo(typeof(int).Assembly.GetName().FullName))){
Kind = ModuleKind.Console,
RuntimeVersion = "v4.0.30319"  //Same runtime version as "CSASM.Core.dll"
};
var asm = new AssemblyDefUser($"CSASM_program_{asmName}", new Version(version));
asm.Modules.Add(mod);
// Adding attribute code omitted for brevity
//Adds types to the module and constructs methods and method bodies for those types based on the CSASM source file in question
Construct(mod, source);
mod.Write(absolute);

可执行文件的生成工作正常。

然而,当尝试运行这个可执行文件时,下面的TypeLoadException被抛出:

System.TypeLoadException: Could not load type 'CSASM.Core.IntPrimitive' from assembly
'CSASM_program_Example, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' due to
value type mismatch.
at Example.Program.csasm_main()

CSASM_program_Example为生成的可执行文件的程序集名称,Example.exe.

类型IntPrimitive实际上是在CSASM.Core.dll程序集中找到的,它也与生成的可执行文件在同一个文件夹中。

由于极度缺乏关于dnLib的文档,我在这里基本上是在黑暗中摸索。


简而言之,是否存在类型试图从错误的程序集加载的原因?
如果是这样,我有什么办法可以补救吗?

在dnSpy中查看程序集显示TypeRefs和MemberRefs引用了正确的程序集,这使得这种困境更加令人沮丧。

在对dnLib DLL进行了非常彻底的检查之后,问题是由于我使用了Importer.ImportDeclaringType(Type).ToTypeDefOrRef(),这导致值类型TypeSigs被注册为类类型TypeSigs。

尽管文档说在方法和字段声明中使用Importer.ImportDeclaringType(Type)而不是Importer.ImportAsTypeSig(Type),你真的不应该使用它。

最新更新