Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите пожалуйста с кодом MSIL, Помогите пожалуйста с кодом MSIL 
:(
    Опции темы
tarasD
Дата 2.10.2007, 14:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 5.5.2007

Репутация: нет
Всего: 1



Помогите пожалуйста! Уже третий день мучаюсь. Никак не могу создать функцию сборки которая сделанная на лету, с помощью System.Reflection.  

Вот код: я создаю функцию PlusTwoDigit, которая принимает два параметра (int32, int32). 
Когда функция принимает один параметр то тогда все нормально, когда два то генерируеться ошибка. 




Код



using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Configuration;
using System.Web;
using System.Configuration;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
using System.Windows.Forms;

namespace ConsoleApplication3
{
    class Foo
    { 
        public const string s = "ukr";
    }


    public class MyAsm
    {
        public int CreateAsm(AppDomain curAppDomain)
        {
            AssemblyName assemblyName = new AssemblyName();
           
            assemblyName.Name = "Taras";
            assemblyName.Version = new Version("1.1.0.0");
           
            

            AssemblyBuilder assembly = curAppDomain.DefineDynamicAssembly(assemblyName,AssemblyBuilderAccess.Save,"C:\\");

            ModuleBuilder module = assembly.DefineDynamicModule("Taras", "Taras.dll");

            
            TypeBuilder helloWorldClass = module.DefineType("MyAsm.HelloWorld", TypeAttributes.Public);

            FieldBuilder msgField = helloWorldClass.DefineField("Msg", Type.GetType("System.String"), FieldAttributes.Private);

            Type[] constructorArgs = new Type[1];
            constructorArgs[0] = Type.GetType("System.String");

            ConstructorBuilder constructor = helloWorldClass.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, constructorArgs);
            ILGenerator constructorIL = constructor.GetILGenerator();
            constructorIL.Emit(OpCodes.Ldarg_0);

            Type objectClass = Type.GetType("System.Object");


            ConstructorInfo superCon = objectClass.GetConstructor(new Type[0]);
            constructorIL.Emit(OpCodes.Call, superCon);

            constructorIL.Emit(OpCodes.Ldarg_0);
            constructorIL.Emit(OpCodes.Ldarg_1);

            constructorIL.Emit(OpCodes.Stfld, msgField);
            constructorIL.Emit(OpCodes.Ret);

            MethodBuilder sayHiMethod = helloWorldClass.DefineMethod("SayHello", MethodAttributes.Public, null, null);

            ILGenerator methodIL = sayHiMethod.GetILGenerator();
            //methodIL.Emit(OpCodes.Ldarg_0);
            
            methodIL.EmitWriteLine("Hello!");
            methodIL.Emit(OpCodes.Ret);



            TypeBuilder classPlus = module.DefineType("MyAsm.Plus", TypeAttributes.Public);
            FieldBuilder field = classPlus.DefineField("digit1",Type.GetType("System.Int32"),FieldAttributes.Public);
            FieldBuilder field1 = classPlus.DefineField("digit2", Type.GetType("System.Int32"), FieldAttributes.Public);

            ConstructorBuilder construct = classPlus.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, null);
            ILGenerator genConst = construct.GetILGenerator();

            genConst.Emit(OpCodes.Ldarg_0);
            genConst.Emit(OpCodes.Call,superCon);
            genConst.Emit(OpCodes.Ret);


            Type[] parametr = new Type[] { typeof(int), typeof(int) };

            //parametr[0] = Type.GetType("System.Int32");
           // parametr[1] = Type.GetType("System.Int32");

            MethodBuilder build = classPlus.DefineMethod("PlusTwoDigit", MethodAttributes.Public, CallingConventions.Standard, null,parametr);



            ILGenerator gen = build.GetILGenerator();
           
       
            gen.Emit(OpCodes.Ldarg,0);
            gen.Emit(OpCodes.Ldarg, 1);
            
            gen.Emit(OpCodes.Stfld, field);

            gen.Emit(OpCodes.Stloc_1);
       

            gen.Emit(OpCodes.Ldarg, 2);
          gen.Emit(OpCodes.Stfld, field1);

          
           

            
            

   
            gen.EmitWriteLine(field);

          
           
            gen.Emit(OpCodes.Ret);


            classPlus.CreateType();


            

            helloWorldClass.CreateType();
            
            
            assembly.Save("Taras.dll");
    

           

            return 0;





        }    
    }
    
    
    class Program
    {
        delegate int MyFuncInvoker(int param1, int param2);
        static void Main(string[] args)
        {
            

            AppDomain curAppDomain = Thread.GetDomain();
            MyAsm asm = new MyAsm();
            asm.CreateAsm(curAppDomain);


            
            Assembly assem = Assembly.LoadFile("C:\\Taras.dll");
            Type t = assem.GetType("MyAsm.HelloWorld");
            Console.WriteLine(t);

            

            object[] par = new object[1];
            par[0] = "Message";
            object obj = Activator.CreateInstance(t,par);

            MethodInfo method = t.GetMethod("SayHello");
            
            
            method.Invoke(obj,null);

            t = assem.GetType("MyAsm.Plus");
            Console.WriteLine(t);
            obj = Activator.CreateInstance(t);

            MethodInfo meth = t.GetMethod("PlusTwoDigit");
            object[] p1 = new object[2];
            p1[0] = 200;
            p1[1] = 2;

            meth.Invoke(obj, p1);


            


        }

        

    }
}


Файл ошибки внизу. 

Присоединённый файл ( Кол-во скачиваний: 5 )
Присоединённый файл  ERROR.JPG 82,93 Kb
PM MAIL   Вверх
stab
Дата 2.10.2007, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

Репутация: 22
Всего: 48



что-то ты видимо с опкодами нахимичил. напиши эквивалентный код на C#, скомпиль, потом выдери из него IL рефлектором\ildasm'ом. или так и делал?


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
tarasD
Дата 2.10.2007, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 5.5.2007

Репутация: нет
Всего: 1



Да вот именно что все так и есть. Я это уже проделал. Но почему то ошибка все-ровно происходит
PM MAIL   Вверх
stab
Дата 2.10.2007, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

Репутация: 22
Всего: 48



код на C# какой?


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
tarasD
Дата 2.10.2007, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 5.5.2007

Репутация: нет
Всего: 1



Ниже представлен код функции которая должна сгенероваться 
Код

public PlusTwoDigit(Int32 _p1, Int32 _p2)
{
     digit1 = _p1;
     digit2 = _p2;
}

PM MAIL   Вверх
stab
Дата 2.10.2007, 16:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

Репутация: 22
Всего: 48



L_0000: ldarg.0 
L_0001: ldarg.1 
L_0002: stfld int32 Test.Digits::digit1
L_0007: ldarg.0 
L_0008: ldarg.2 
L_0009: stfld int32 Test.Digits::digit2
L_000e: ret 

вроде так получается, а у тебя опкоды немного другие. особенно сомнителен: gen.Emit(OpCodes.Stloc_1);


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
tarasD
Дата 2.10.2007, 16:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 5.5.2007

Репутация: нет
Всего: 1



Забери пожалуйста этот опкод, и попробуй. Ничего н выходит все всеровно
PM MAIL   Вверх
stab
Дата 2.10.2007, 16:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

Репутация: 22
Всего: 48



забирать его не надо, его надо заменить на ldarg. кстати, похоже у тебя соглашение вызова не то, попробуй CallingConventions.HasThis.


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
tarasD
Дата 2.10.2007, 16:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 5.5.2007

Репутация: нет
Всего: 1



А что это значит
PM MAIL   Вверх
stab
Дата 3.10.2007, 05:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

Репутация: 22
Всего: 48



значит что это метод экземпляра класса, т.е. имеет this.


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0470 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.