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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Выполнить строку, Помотите пожайлуста. 
:(
    Опции темы
KuZyagroup
Дата 25.5.2007, 01:36 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


magento solution
**


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

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



Можно ли в C# выполнить строку:

Код

string myString = "myFunction();";
private void myFunction()
{
  // -- smth code
}

private void elseMyFunction()
{
  // --  smth code
  SuperFunction(myString);
  // -- smth code
}


То есть если ли такая SuperFunctrion которая строку выполняет как текст прорграммы. В моем примере она должна запустить MyFunction();
PM MAIL   Вверх
archimed7592
Дата 25.5.2007, 01:43 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 7
Всего: 93



Цитата(KuZyagroup @  25.5.2007,  01:36 Найти цитируемый пост)
В моем примере она должна запустить MyFunction(); 

для конкретно этого примера(выполнить ф-цию, имея её имя в строковой переменной) точно подойдёт reflection...
насчёт произвольного кода не уверен... вроде никак низя(кроме как запускания компилятора, получения дин. либы, run-time линковки и запуска нужной entry-point)

Это сообщение отредактировал(а) archimed7592 - 25.5.2007, 01:43


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
tol05
Дата 25.5.2007, 09:07 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 63
Всего: 170



Цитата(archimed7592 @  25.5.2007,  01:43 Найти цитируемый пост)
насчёт произвольного кода не уверен... вроде никак низя(кроме как запускания компилятора, получения дин. либы, run-time линковки и запуска нужной entry-point)



archimed7592, c помощью рефлексии можно выполнить вообще все, а динамически сгенерированный код сбросить с поток, записать в файл, методом Process.Start() запустить компилятор, скомпилить и запустить  smile  

только зачем все это? зачем будить лихо, пока оно тихо? smile Я так понял, что код как таковой создавать не нужно?

не проще ли KuZyagroup, в твою функцию SuperFunctrion передавать какой-нибудь флаг, по значению которого она выбирала бы из существующих ф-ций ту, которую нужно выполнить? Так винда делает, да и делегаты. Передается цифровой ID метода в качестве флага, ну а потом - что-то типа switch-case? 
А еще лучше сразу через делегат. Передавай его как параметр в SuperFunctrion, а устанавливай там, где ты устанавливаешь строку с именем метода.

Это сообщение отредактировал(а) tol05 - 25.5.2007, 09:14


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
archimed7592
Дата 25.5.2007, 11:17 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 7
Всего: 93



Цитата(tol05 @  25.5.2007,  09:07 Найти цитируемый пост)

archimed7592, c помощью рефлексии можно выполнить вообще все, а динамически сгенерированный код сбросить с поток, записать в файл, методом Process.Start() запустить компилятор, скомпилить и запустить  smile  
я сказал то же самое smile

Цитата(archimed7592 @  25.5.2007,  01:43 Найти цитируемый пост)
(кроме как запускания компилятора, получения дин. либы, run-time линковки и запуска нужной entry-point

 smile

Добавлено через 1 минуту и 10 секунд
или ты имеешь ввиду, что без компилятора, с помощью рефлексии можно выполнить произвольный код?


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
Ch0bits
Дата 25.5.2007, 11:31 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Python Dev.
****


Профиль
Группа: Завсегдатай
Сообщений: 2124
Регистрация: 21.2.2005
Где: Казань

Репутация: 9
Всего: 62



Цитата(tol05 @  25.5.2007,  09:07 Найти цитируемый пост)
только зачем все это? зачем будить лихо, пока оно тихо?

Чтобы написать новый магаполиморфный самосебяпрограммирующий супервирус с AI! Который захватит все компы с Вистой! И положит игровые серверы Пентагона с контрой и батлфилдом! И имя ему - SKYNET.  smile  smile  smile 
PM WWW   Вверх
tol05
Дата 25.5.2007, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 63
Всего: 170



Извини, 
archimed7592, видно не с той стороны читал твой пост  smile 

Но и тут ты не до конца прав. Можно сделать все
Цитата из Троелсена (второе издание, для .Net 1.x)
Цитата

при помощи типов из System.Reflect!on.Emit вполне возможно добавлять новые типы и члены в представление уже загруженной в оперативную память сборки.

Сам не пробовал, но если бы надо было, попробовал бы так:
Код

AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "MyAssembly";
assemblyName.Version = new Version("1.0.0.0");
...
AssemblyBuilder assembly = curAppDomain.DefineDynamicAssembly(assemblyName.AssemblyBuiIderAccess.Save);
ModuleBuilder module = assembly.DefineOynamicModule("MyAssembly", "НуAssembly.dll");
TypeBuilder helloWorldClass = module.DefineType("MyAssembly.HelloWorld", TypeAttributes.Public);
FieldBuilder msgField = helloWorldClass.DegineField("Msg", Type.GetType("System.String"), FieldAttributes.Private):
...
ConstructorBuilder constructor = helloWorldClass.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, ...);
...
MethodInfo entry = Assembly.Load(assemblyName).EntryPoint;
entry.Invoke (...);

 smile 

Это сообщение отредактировал(а) tol05 - 25.5.2007, 11:45


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
archimed7592
Дата 25.5.2007, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 7
Всего: 93



tol05, я имею ввиду, что, если у тебя есть строка, прелставляющая из себя код на любом .net языке, скажем, c#...
тебе понадобится, либо компилятор, либо самому транслировать этот код в примитивы, которые умеет делать reflection... я не прав?


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
tol05
Дата 25.5.2007, 12:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 63
Всего: 170



Что-то я запутался уже...  smile 

Цитата(archimed7592 @  25.5.2007,  01:43 Найти цитируемый пост)
для конкретно этого примера(выполнить ф-цию, имея её имя в строковой переменной) точно подойдёт reflection...
насчёт произвольного кода не уверен... вроде никак низя(кроме как запускания компилятора, получения дин. либы, run-time линковки и запуска нужной entry-point)

было понято мной как: "нельзя в сборке написать что попало, запустить и выполнить". Ответ: Можно.  smile (По крайней мере, запустить, а выполнится оно или нет - уже от "что попало" зависит)


Цитата(archimed7592 @  25.5.2007,  11:17 Найти цитируемый пост)
или ты имеешь ввиду, что без компилятора, с помощью рефлексии можно выполнить произвольный код? 

Ответ: ага!


Цитата(archimed7592 @  25.5.2007,  11:55 Найти цитируемый пост)
я имею ввиду, что, если у тебя есть строка, прелставляющая из себя код на любом .net языке, скажем, c#...
тебе понадобится, либо компилятор, либо самому транслировать этот код в примитивы, которые умеет делать reflection... я не прав?


Компилятор не понадобится (второй пост пытается продемонстрировать это). Что значит "самому транслировать этот код в примитивы"? Раз reflection "умеет делать", пусть и делает smile
Как это самому? Ну код хоть какой-нибудь, конечно все-таки надо написать smile 
я и написал. Наверняка он работать не будет, я же не тестил, но возможности-то есть? Просто готовый IL грузится сразу в память домена, а дальше - все как положено, вызов -> JIT -> богатство и слава  smile 

Я не хотел усложнять. Тот же Троелсен гораздо больше написал, чем я цитировал... Может конечно уже старый Троелсен не у каждого есть, тогда допишу. Что-то типа этого будет:
Код

ConstructorBuilder constructor = helloWorldClass.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, ...);
...
ILGenerator constructorIL = constructor.GetlLGenerator();
constructorIL.Emit(OpCodes.Ldarg_0);
Type objectClass = Type.GetType("System.Object");
Constructorlnfo superConstructor = objectClass.GetConstructor(new Type[0]):
constructorIL.Emit(OpCodes.Call, superConstructor):
constructorIL.Emit(OpCodes.Ldarg_0):
constructorIL.Emit(Opcodes.Idarg_1);
constructorIL. Emit (Opcodes.StfId,msgFleld);
constructorIL.Em1t(OpCodes.Ret);

MethodBuilder getMsgMethod = helloWorldClass.DefineMethod("GetMsg", MethodAttrlbutes.Public, Type.GetType("System.String"), null):
ILGenerator methodIL = getMsgMethod.GetlLGenerator():
methodll.Emit(OpCodes.Ldarg_0);
methodIL.Emit(Opcodes.Ldf1d. msgField);
methodIL.Emi t(Opcodes.Ret):

MethodBuilder sayHiMethod = helloWorldClass.DefineMethod("SayHello", MethodAttributes.Public, null, null);
methodIL = sayHiMethod.GetlLGenerator();
methodIL.EmitWriteLine("Hello there!");
methodIL.Emit(OpCodes.Ret);

helloWorldClass.CreateType();

assembly.Save("MyAssembly.dl 1");



--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
Voyager
Дата 25.5.2007, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 3
Всего: 18



Смотри в сторону CSharpCodeProvider  и CodeDom.
PM   Вверх
archeg
Дата 25.5.2007, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 612
Регистрация: 6.1.2007
Где: Киев

Репутация: 11
Всего: 27



Reflection.Emit позволяет использовать CIL-код, создавая находу части кода и сразу же их запуская с помощью JIT
CodeDOM позволяет создавать на C#, VB.NET, C++, может еще чем-та. После этого происходит компиляция языка и запуск его (уже другая сборка). В зависимости от того, что нужно - нужно использовать либо то, либо то

P.S. Reflection и Reflection.Emit - немного разные вещи  smile 

Это сообщение отредактировал(а) archeg - 25.5.2007, 14:11


--------------------
ИМХО задница есть универсальный интерфейс. Ибо через задницу можно сделать абсолютно ВСЕ (bash.org.ru)

Дядька всегда можно спросить в аське, если не задалбывать - не откажет smile
И вообще, на самом деле я студент, и ненавижу обращение на "Вы") Тут все свои  ;)
PM MAIL ICQ Jabber   Вверх
KuZyagroup
Дата 30.5.2007, 04:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


magento solution
**


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

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



Цитата(archimed7592 @ 25.5.2007,  01:43)
Цитата(KuZyagroup @  25.5.2007,  01:36 Найти цитируемый пост)
В моем примере она должна запустить MyFunction(); 

для конкретно этого примера(выполнить ф-цию, имея её имя в строковой переменной) точно подойдёт reflection...
насчёт произвольного кода не уверен... вроде никак низя(кроме как запускания компилятора, получения дин. либы, run-time линковки и запуска нужной entry-point)

А можно подетальней про reflection.  smile для моего кода.
П.С. А метод через компилятор слишком неоправданый в случае когда надо упростить

Код

private void webBrowserCommand_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            WebBrowser wb = this.webBrowserCommand;
            string htmlTitle = wb.DocumentTitle;
            string htmlText = wb.DocumentText.Substring(40 + htmlTitle.Length);
            htmlText = showXMLdisableChars(htmlText);
            switch (htmlTitle)
            {
                case "Login":
                    Login(htmlText);
                    break;
                case "loadKontactList":
                    loadKontactList(hideXMLdisableChars(htmlText));
                    break;
                case "addKontact":
                    addKontact(htmlText);
                    break;
                case "deleteKontact":
                    deleteKontact(htmlText);
                    break;
                case "addGroup":
                    addGroup(htmlText);
                    break;
                case "renameGroup":
                    renameGroup(htmlText);
                    break;
                case "deleteGroup":
                    deleteGroup(htmlText);
                    break;
                case "autoComplite":
                    wb.Document.All["passw"].SetAttribute("VALUE", this.passw);
                    wb.Document.InvokeScript("formSubmit");
                    break;
                default:
                    break;
            }
        }


Добавлено через 5 минут и 22 секунды
Цитата

не проще ли KuZyagroup, в твою функцию SuperFunctrion передавать какой-нибудь флаг, по значению которого она выбирала бы из существующих ф-ций ту, которую нужно выполнить? Так винда делает, да и делегаты. Передается цифровой ID метода в качестве флага, ну а потом - что-то типа switch-case? 
А еще лучше сразу через делегат. Передавай его как параметр в SuperFunctrion, а устанавливай там, где ты устанавливаешь строку с именем метода.

Спасибо за ответ
Пока оно в таком виде и есть. Про делегаты только сегодня первый раз услышал - посмотрю, разберусь может поможет.

Добавлено через 6 минут и 47 секунд
Voyager, Спасибо за ответ, обязательно посмотрю
PM MAIL   Вверх
archimed7592
Дата 30.5.2007, 04:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 7
Всего: 93



KuZyagroup, я точно не помню... вирутальную машину запускать влом(у меня там студия smile)
что тебе нужно: ознакомится с пространством имён Reflection, найти там ф-ции для поиска ф-ций(сорри за каламбур) и ф-ции для запуска произвольной ф-ции с передачей ей определенных аргументов...


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
KuZyagroup
Дата 30.5.2007, 04:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


magento solution
**


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

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



archeg, спасибо за ответ
Цитата

Reflection.Emit позволяет использовать CIL-код, создавая находу части кода и сразу же их запуская с помощью JIT
CodeDOM позволяет создавать на C#, VB.NET, C++, может еще чем-та. После этого происходит компиляция языка и запуск его (уже другая сборка). В зависимости от того, что нужно - нужно использовать либо то, либо то

P.S. Reflection и Reflection.Emit - немного разные вещи   

А можно пример
PM MAIL   Вверх
archimed7592
Дата 30.5.2007, 04:22 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 7
Всего: 93



вот пример из мсдн:
Код
using System;
using System.Reflection;

class Program
{

    // Method to get:
    public void MethodA() { }


    static void Main(string[] args)
    {

        // Get MethodA()
        MethodInfo mInfo = typeof(Program).GetMethod("MethodA");
        Console.WriteLine("Found method: {0}", mInfo);

    }
}

отсюда

Добавлено через 4 минуты и 54 секунды
вот ещё
Код
using System;
using System.Reflection;
using System.Security.Permissions;

// Declare three delegate types for demonstrating the combinations
// of static versus instance methods and open versus closed
// delegates.
//
public delegate void D1(C c, string s);
public delegate void D2(string s);
public delegate void D3();

// A sample class with an instance method and a static method.
//
public class C
{
    private int id;
    public C(int id) { this.id = id; }

    public void M1(string s) 
    { 
        Console.WriteLine("Instance method M1 on C:  id = {0}, s = {1}",
            this.id, s);
    }
  
    public static void M2(string s)
    { 
        Console.WriteLine("Static method M2 on C:  s = {0}", s); 
    }
}

public class Example
{
    public static void Main()
    {
        C c1 = new C(42);

        // Get a MethodInfo for each method.
        //
        MethodInfo mi1 = typeof(C).GetMethod("M1", 
            BindingFlags.Public | BindingFlags.Instance);
        MethodInfo mi2 = typeof(C).GetMethod("M2",
            BindingFlags.Public | BindingFlags.Static);

        D1 d1;
        D2 d2;
        D3 d3;


        Console.WriteLine("\nAn instance method closed over C.");
        // In this case, the delegate and the
        // method must have the same list of argument types; use
        // delegate type D2 with static method M1.
        //
        Delegate test = 
            Delegate.CreateDelegate(typeof(D2), c1, mi1, false);

        // Because false was specified for throwOnBindFailure 
        // in the call to CreateDelegate, the variable 'test'
        // contains null if the method fails to bind (for 
        // example, if mi1 happened to represent a method of  
        // some class other than C).
        //
        if (test != null)
        {
            d2 = (D2) test;

            // The same instance of C is used every time the 
            // delegate is invoked.
            d2("Hello, World!");
            d2("Hi, Mom!");
        }


        Console.WriteLine("\nAn open instance method.");
        // In this case, the delegate has one more 
        // argument than the instance method; this argument comes
        // at the beginning, and represents the hidden instance
        // argument of the instance method. Use delegate type D1
        // with instance method M1.
        //
        d1 = (D1) Delegate.CreateDelegate(typeof(D1), null, mi1);

        // An instance of C must be passed in each time the 
        // delegate is invoked.
        //
        d1(c1, "Hello, World!");
        d1(new C(5280), "Hi, Mom!");


        Console.WriteLine("\nAn open static method.");
        // In this case, the delegate and the method must 
        // have the same list of argument types; use delegate type
        // D2 with static method M2.
        //
        d2 = (D2) Delegate.CreateDelegate(typeof(D2), null, mi2);

        // No instances of C are involved, because this is a static
        // method. 
        //
        d2("Hello, World!");
        d2("Hi, Mom!");


        Console.WriteLine("\nA static method closed over the first argument (String).");
        // The delegate must omit the first argument of the method.
        // A string is passed as the firstArgument parameter, and 
        // the delegate is bound to this string. Use delegate type 
        // D3 with static method M2. 
        //
        d3 = (D3) Delegate.CreateDelegate(typeof(D3), 
            "Hello, World!", mi2);

        // Each time the delegate is invoked, the same string is
        // used.
        d3();
    }
}

/* This code example produces the following output:

An instance method closed over C.
Instance method M1 on C:  id = 42, s = Hello, World!
Instance method M1 on C:  id = 42, s = Hi, Mom!

An open instance method.
Instance method M1 on C:  id = 42, s = Hello, World!
Instance method M1 on C:  id = 5280, s = Hi, Mom!

An open static method.
Static method M2 on C:  s = Hello, World!
Static method M2 on C:  s = Hi, Mom!

A static method closed over the first argument (String).
Static method M2 on C:  s = Hello, World!
 */

отсюда


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
KuZyagroup
Дата 30.5.2007, 04:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


magento solution
**


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

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



Спасиб огромное ))
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

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


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

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


 




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


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

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