C#Reflection.Emit外部c ++ dll抛出BadImageFormatException

时间:2017-06-18 03:18:58

标签: c# c++ .net dll reflection.emit

我试图生成调用dll库的程序集,但偶然发现无法解决的错误。 我编译了用c ++编写的sll.dll(只有一个类 - StackInt)并使用参数CLR x86 Release编译。

#pragma once
// sll.dll
using namespace System;
namespace SLCollections {
    public ref class StackInt
    {
    private:
        array< Int32 >^ data;
        Int32 size, capacity;
        void grow() {
            array< Int32 >^ newdata = gcnew array< Int32 >(capacity << 1);
            for (Int32 i = 0; i < capacity; i++) {
                newdata[i] = data[i];
            }
            capacity <<= 1;
            data = newdata;
        }
    public:
        StackInt() : size(0), capacity(2), data(gcnew array< Int32 >(2)) {}
        void push(Int32 item) {
            if (capacity >= size) {
                grow();
            }
            data[size++] = item;
        }
        Int32 pop() {
            return data[--size];
        }
        Int32 top() {
            return data[size - 1];
        }
        bool isEmpty() {
            return size == 0;
        }
    };
}

我希望在使用Reflection Emit以C#编写的动态生成的程序集中使用此库,并使用x86 Release配置选项进行编译。 C#代码使用sll.dll(引用的dll):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection.Emit;
using SLCollections;
using System.Reflection;

namespace Generator
{
class Program 
{
    static void Main(string[] args)
    {
        string moduleName = "test.exe";
        try
        {
            // worked code!
            //StackInt stack = new StackInt();
            //stack.push(10);

            AssemblyName name = new AssemblyName(System.IO.Path.GetFileNameWithoutExtension(moduleName));
            AssemblyBuilder asmb = AppDomain.CurrentDomain
                .DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave);
            ModuleBuilder modb = asmb.DefineDynamicModule(moduleName);
            TypeBuilder typeBuilder = modb.DefineType("Foo");
            MethodBuilder methb = typeBuilder.DefineMethod("Main",
                MethodAttributes.Static, typeof(void), 
                Type.EmptyTypes);

            ILGenerator il = methb.GetILGenerator();
            Type stackType = typeof(StackInt);
            LocalBuilder localStackBuilder = il.DeclareLocal(stackType);
            Type[] t = new Type[0];

            il.Emit(OpCodes.Newobj,
               stackType.GetConstructor(t));

            il.Emit(OpCodes.Stloc, localStackBuilder);
            il.Emit(OpCodes.Ldloc, localStackBuilder);

            MethodInfo pushMethod = stackType.GetMethod(
                "push", new Type[] { typeof(int) });

            il.Emit(OpCodes.Ldc_I4_4);
            il.Emit(OpCodes.Callvirt, pushMethod);
            il.Emit(OpCodes.Pop);

            // return
            il.Emit(OpCodes.Ret);
            typeBuilder.CreateType();
            modb.CreateGlobalFunctions();
            asmb.SetEntryPoint(methb);
            asmb.Save(moduleName);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.StackTrace);
        }
    }
}
}

可以创建包含在sll.dll中的类StackInt的对象,并使用using SLCollections指令调用它的方法。当我编译并保存汇编时,一切都很好。但是,程序集test.exe以错误开始:

System.BadImageFormatException was unhandled Message: 
An unhandled exception of type 'System.BadImageFormatException' 
occurred in mscorlib.dll Additional information:
Failed to load file or assembly 
"SLL, Version=1.0.6354.41871, Culture=neutral, PublicKeyToken=null"
or one of their dependencies. 
An attempt was made to load a program that has an incorrect format.

生成的程序集中的反汇编代码很好。

我错在哪里?

0 个答案:

没有答案