Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Поиск функции по её имени в теле программы

13K
07 ноября 2005 года
skf
9 / / 07.11.2005
Всем привет. Подскажите плиз, как найти и выполнить функцию в теле программы, например:

1) существует переменная funct_name типа string в которй содержится имя функции
2) существует переменная funct_param типа string в которой содержатся аргументы для этой функции

как мне найти эту функцию в теле программы и выполнить?

и еще: как можно получить результат её работы в другую переменную, например funct_result?
243
08 ноября 2005 года
pacific_7
1.9K / / 06.09.2004
Цитата:
Originally posted by skf
Всем привет. Подскажите плиз, как найти и выполнить функцию в теле программы, например:

1) существует переменная funct_name типа string в которй содержится имя функции
2) существует переменная funct_param типа string в которой содержатся аргументы для этой функции

как мне найти эту функцию в теле программы и выполнить?

и еще: как можно получить результат её работы в другую переменную, например funct_result?


Что-то я ничё не понял. Что ты хочешь сделать? Найти функцию в чужом exe файле и выполнить ее? Нафига? Если на то пошло, то для этого существует такая штука как библиотеки (dll) - вот из них и производится экспорт функции для выполнения.
Или, если не подходит, то изложи подробнее свою проблему.

13K
08 ноября 2005 года
skf
9 / / 07.11.2005
Я хочу найти и выполнить функцию в своей программе, зная её имя, которое хранится в переменной.
Иными словами, мне нужен пример кода, который бы находил и выполнял функцию по имени в моей программе.
239
08 ноября 2005 года
Dolonet
1.7K / / 20.05.2000
Цитата:
Originally posted by skf
Я хочу найти и выполнить функцию в своей программе, зная её имя, которое хранится в переменной.
Иными словами, мне нужен пример кода, который бы находил и выполнял функцию по имени в моей программе.

Это зависит от языка программирования. И совсем не обязательно это возможно. Например, в PHP это реализуется так:

 
Код:
$function_name = 'abc';

function abc($a, $b, $c) {
    return $a+$b+$c;
}

echo @$function_name(1, 2, 3);
255
08 ноября 2005 года
Dart Bobr
1.4K / / 09.04.2004
Цитата:
Originally posted by skf
Всем привет. Подскажите плиз, как найти и выполнить функцию в теле программы, например:

1) существует переменная funct_name типа string в которй содержится имя функции
2) существует переменная funct_param типа string в которой содержатся аргументы для этой функции

как мне найти эту функцию в теле программы и выполнить?

и еще: как можно получить результат её работы в другую переменную, например funct_result?



1) описані ли прототипі данной функции?
2) является ли функция методом какого-то класса или нет?
3) на чем пишешь?

Если ті используешь не асмовій компилятор, то думаю єто будет нелегко - практически все компиляторі имеют особенность замангливать имена функций(не знаю правда все ли функции замангливаются.)
Если определяешь прототип, то по-идее задачка упрощается. Тогда, короче, нужно будет раскопать тестовій екзешник и посмотреть где єти прототипі определяются.

5
08 ноября 2005 года
hardcase
4.5K / / 09.08.2005
Цитата:
Originally posted by skf
Я хочу найти и выполнить функцию в своей программе, зная её имя, которое хранится в переменной.
Иными словами, мне нужен пример кода, который бы находил и выполнял функцию по имени в моей программе.


Если это твой код, то его можно переписать таким образом, что бы использовать указатель на функцию, передавать его куда тебе нужно, вызывать в конце концов.
В делфях например есть специальный процедурный тип для хренения адресов функций и процедур.

Код:
type
  TMyProcType = procedure (A,B: integer);

var
  P: TMyProcType;

procedure SomeProc(A,B: integer);
  begin
     DoSomething;
  end;

begin
  P:=SomeProc;  //инициализация
  P (10,14);  //вызов
end;

С функциями аналогично.
13K
08 ноября 2005 года
skf
9 / / 07.11.2005
Всем спасибо за помощь! Код hardcase'a как раз то что нужно.
13K
08 ноября 2005 года
skf
9 / / 07.11.2005
Поискал в хелпе по делфи описание этого типа, ничего нет;)

Можно ли как-то получить результат выполнения функции в другую переменную?

TMyProcType = procedure (A,B: integer); - тоесть для кажой процедуры нужно определять новый тип? А если у меня функции принимают разное количество параметров? Может есть какой-нибудь другой способ? Этакий eval() для делфи?

P.S. Модераторам: перенисите плиз треад в вопросы по делфи
5
08 ноября 2005 года
hardcase
4.5K / / 09.08.2005
Цитата:
Originally posted by skf
Поискал в хелпе по делфи описание этого типа, ничего нет


Какраз в хэлпах всё написано хорошо. В индексе напиши: procedural type - найдёшь что искал :)
В делфи каждая функция имеет собственный процедурный тип (кламбур) - это то, как она объявлена.

 
Код:
type
  TFirst = function (A,B: integer): integer; stdcall;
  TSecond = function (A,B: integer): integer; register;

Эти два объявления будут совершенно различными (stdcall - передача параметров через стек register - через регистры).
Код:
//имеет тип TFirst
function First(A,B: integer): integer; stdcall;
  begin
      Result:=A+B;
  end;

//имеет тип TSecond
function Second(A,B: integer): integer; register;
  begin
      Result:=A+B;
  end;

var
   Res1: integer;
   Res2: integer;

   F: TFirst;
   S: TSecond;

begin
   F:=First;
   S:=Second;
   Res1:=F (10, 15);
   Res2:=S (54,  34);
end;

Кстати, в делфи различаются два рода укателей: указатель на обычную функцию и на функцию-член класса (как статическую, так и виртуальную).
13K
08 ноября 2005 года
skf
9 / / 07.11.2005
То есть реализовать мою задумку на делфях невозможно? Может тогда асмовые инклуды решат задачу??
5
08 ноября 2005 года
hardcase
4.5K / / 09.08.2005
Цитата:
Originally posted by skf
То есть реализовать мою задумку на делфях невозможно? Может тогда асмовые инклуды решат задачу??


Какая задумка?
Если ты хочешь получить значение функции, адрес которой лежит в переменной процедурного типа, то читай внимательнее предыдущий пост (код).

Если ты хочешь получить адрес функции по её имени - то в Делфи этого в принципе сделать не возможно, не прибегая к дополнительному программированию (сохраниение имени и адреса в собственной хеш таблице и т.п. - но это уже изврат какой-то) - объектный код не содержит имён функций (за исключением секции exports).

Что вообще ты хочешь сделать?

13K
09 ноября 2005 года
skf
9 / / 07.11.2005
Пишу RAT сервер, и чтобы не парсить команды клиента кейсом, хочу один раз написать такую вот универсальную функцию:D
А то допишешь новую команду, придёться кейс переписывать...
Буду наверно свою таблицу импорта делать... Тока вот думаеца мне что это еще более геморно чем кейс переписывать каждый раз:{
5
09 ноября 2005 года
hardcase
4.5K / / 09.08.2005
Цитата:
Originally posted by skf
Пишу RAT сервер, и чтобы не парсить команды клиента кейсом, хочу один раз написать такую вот универсальную функцию:D
А то допишешь новую команду, придёться кейс переписывать...
Буду наверно свою таблицу импорта делать... Тока вот думаеца мне что это еще более геморно чем кейс переписывать каждый раз:{


Можно сделать так:
Каждая команда - некоторый класс.
При создании экземпляа класса происходит регистрация новой команды в твоей таблице команд. При получении команды ты ищешь связанную, с ней запись в таблице команд, а это и будет экземпляр класса этой команды и передаёшь в его метод, например Execute;

Код:
type
  TCommand = class
    protected
      fCommand: string;
    public
      procedure Execute(const Params: string); virtual; abstract;
      property Command: string read fCommand;
  end;

  TCommandTable = class
    public
      function RegisterCommand(Cmd: TCommand): boolean;
      function ExecuteCommand(const Cmd: string; const Params: string);
  end;

TCommand - абстрактный класс для всех твоих комманд
TCommandTable - таблица команд, она будет осуществлять поиск и выполнение комманд. Её можно организовать как хеш таблицу или дерево.

При создании новой команды ты просто наследуешь новый класс от TCommand и заполняешь поле fCommand := 'NewCommandName'; в конструкторе - по нему ты будешь искать команду в таблице.
Потом создаёшь экземпляр этого класса и регистрируешь его в таблице.
ExecuteCommand будет вызывать метод Execute в соответствующей зарегистрированной команде.

Надеюсь идея вам ясна?
13K
09 ноября 2005 года
skf
9 / / 07.11.2005
Общая идея понятна, но мне еще не приходилось так плотно работать с классами в делфи.
Если можешь, разжуй всё попобробнее
5
09 ноября 2005 года
hardcase
4.5K / / 09.08.2005
Цитата:
Originally posted by skf
Общая идея понятна, но мне еще не приходилось так плотно работать с классами в делфи.
Если можешь, разжуй всё попобробнее


Вот рыба. что не понятно, стучи в асю 263-271-807

Код:
type
  TCommand = class
    private
      fCommand: string;
    public
      procedure Execute(const Params: string); virtual; abstract;
      property Command: string read fCommand;
  end;//of class

  TCommandTable = class
    protected
      procedure AddCommand(Cmd: TCommand);
      function FindCommand(const Cmd: string): TCommand;
      procedure DeleteCommands;
    public
      destructor Destroy; override;
      function RegisterCommand(Cmd: TCommand): boolean;
      function ExecuteCommand(const Cmd: string; const Params: string): boolean;
  end;//of class

  //пример команды
  TSimpleCommand = class(TCommand)
    public
      constructor Create;
      procedure Execute(const Params: string); override;
  end;//of class

procedure TCommandTable.Destroy;
  begin
    DeleteCommands;
  end;

procedure TCommandTable.AddCommand(Cmd: TCommand);
  begin
    //добавляем новую команду в таблицу
    //с Cmd.Command находится идентификатор комманды

    //таблицу команд можно организовать как хэш таблицу
    //в Делфи есть специальный класс: THashedStringList
  end;

function TCommandTable.FindCommand(const Cmd: string): TCommand;
  begin
    //осуществляем поиск команды Cmd в таблице и возвращаем
    //как результат
    //если не нашли, то возвращаем nil
  end;

procedure TCommandTable.DeleteCommands;
  begin
    //очищаем таблицу
  end;

function TCommandTable.RegisterCommand(Cmd: TCommand): boolean;
  begin
    if FindCommand(Cmd.Command) then Result:=false
    else begin
        AddCommand(Cmd);
        Result:=true;
    end;
  end;

function TCommandTable.ExecuteCommand(const Cmd, Params: string): boolean;
  var C: TCommand;
  begin
    c:=FindCommand(Cmd);
    if C = nil then Result:=false
    else begin
        C.Execute(Params);
        Result:=true
    end;
  end;

constructor TSimpleCommand.Create;
  begin
    fCommand:='MyCommandName';
  end;

procedure TSimpleCommand.Execute(const Params: string);
  begin
    //нужно переопределять этот метод
    //чтобы придать комманде функциональность
  end;

var
  CmdTable: TCommandTable;
  Cmd: TSimpleCommand;

begin
//создаём таблицу команд
  CmdTable:=TCommandTable.Create;
//создаём объект команды
  Cmd:=TSimpleCommand.Create;
  if not CmdTable.RegisterCommand(Cmd) //регистрация провалилась
  then begin
     Cmd.Free;
  end else begin
     CmdTable.ExecuteCommand ('MyCommandName', 'Parameters' );
  end;
end;
303
10 ноября 2005 года
makbeth
1.0K / / 25.11.2004
Предлагаю немного другой вариант(но из той же оперы :) ). Я вот подумал, нафига создавать каждый раз экземпляр команды, если там просто вызывается функция? Можно использовать просто классовые ссылки:
Код:
type
    TCommand = class
        class function Execute(const Params: string): string; virtual; abstract;
    end;
    TCommandClass = class of TCommand;
 
    TCommandTable = class
    private
        FCommandList: TClassList; // Здесь храним команды
        function GetCommand(Name: string): TCommandClass;
    public
        function RegisterCommand(Cmd: TCommandClass): boolean;
        property Commands[Name: string]: TCommandClass read GetCommand; default;
        // Ну и еще что-нибудь...
    end;  

    // Какая-то команда
    TSimpleCommand = class (TCommand)
    public
        class function Execute(const Params: string): string; override;
    end;

// Далее все тоже самое
// GetCommand ищет в списке команду по имени ее класса
function GetCommand(Name: string): TCommandClass;
var i, count: Integer;
begin
    Result:=nil;
    count:=FCommandList.Count;
    for i:=0 to count - 1 do
        if FCommandList.ClassName = Name then
        begin
            Result:=FCommandList as TCommandClass;
            Exit;
        end;
end;

// Как все это работает?
begin
    //Где - то уже создана CommandTable...
    // Регистрируем команду:
    CommandTable.RegisterCommand(TSimpleCommand);
    // Выполняем комманду
    some_result:=CommandTable['TSimpleCommand'].Execute(some_params);
    // А можно просто вот так ;)
    some_result:=TSimpleCommand.Execute(some_params);
end;
5
10 ноября 2005 года
hardcase
4.5K / / 09.08.2005
Цитата:
Originally posted by makbeth
Предлагаю немного другой вариант(но из той же оперы :) ). Я вот подумал, нафига создавать каждый раз экземпляр команды, если там просто вызывается функция? Можно использовать просто классовые ссылки:


Тоже неплохо, но до определённого момента - вдруг нам понадобятся какие-то связывания при выполнении программы, например, команда управляет каким нибудь левым объектом.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог