创建一个从.dll中调用函数的.exe



所以我有一个带有函数的.dll(静态或实例,我可以改变它,并且仍然有效),我想创建一个带有Main作为入口点的Exe,读取命令行,并从.dll

调用函数

这是我要调用的方法

 public static void Add(String a, String b)
 {
  Console.WriteLine( "{0} + {1}=  {2}", a, b , a+b);
 }

-所以我加载DLL程序集,并获得具有我想要的函数的类型

        Assembly asmLoaded = Assembly.LoadFrom(nameDLL);
        Type baseType = asmLoaded.GetType(typeName);

-为新的Exe创建新的程序集、模块和类型

AssemblyName aName = new AssemblyName("AppAsm");
        AssemblyBuilder ab =
        AppDomain.CurrentDomain.DefineDynamicAssembly(
            aName,
            AssemblyBuilderAccess.Save);
        ModuleBuilder mb =
        ab.DefineDynamicModule("AppMod", typeName + methodName + ".exe");
        TypeBuilder tb = mb.DefineType("AppType", TypeAttributes.Public);

-从我想要调用的方法中获取methodInfo,以及它的参数Types[],用于后面的Emit(Opcodes.Call,…);

-然后我定义方法"Main"作为入口点

 MethodBuilder metb = tb.DefineMethod("Main", MethodAttributes.Public |
            MethodAttributes.Static, null, new Type[] { typeof(String[])});
 ab.SetEntryPoint(metb);

-通过使用ildasm,我尝试做这部分,生成IL

 ILGenerator il = metb.GetILGenerator();
 for (int i = 0; i <paramTypes.Length; ++i)
        {
            il.Emit(OpCodes.Ldarg_0); // get the String[], in 0 cause its static
            il.Emit(OpCodes.Ldc_I4,i);
            il.Emit(OpCodes.Ldelem_Ref);
            il.Emit(OpCodes.Stloc, i);
        }         
        il.Emit(OpCodes.Ldloc, 0);
        il.Emit(OpCodes.Ldloc, 1);
        il.EmitCall(OpCodes.Call, wantedMethodInfo, paramTypes);
        il.Emit(OpCodes.Ret);

-最后创建Type,并保存assemblyBuilder

tb.CreateType();
ab.Save(typeName + methodName + ".exe");

当然它不起作用,xD当我运行由一些值生成的exe时,它抛出系统。公共语言运行时检测到一个无效的程序。在AppTYpe。Main (String []) 我想我可能应该弹出,一些东西从堆栈中,但不确定。

我会使用表达式树来生成这个(简单的)Main函数。可以使用CompileToMethod方法将表达式树转换为MethodBuilder

同样,调试的方法是运行PEVerify。

无法告诉您IL具体在哪里出错,因为我看不到您要调用的方法。你得把这个扔掉。使用表达式树

另一个奇怪的选择是你完全使用了局部变量。你可以这样做:

ldelem 0
ldelem 1
ldelem ...
call
ret

伪代码

相关内容

  • 没有找到相关文章

最新更新