Поиск функции по её имени в теле программы
1) существует переменная funct_name типа string в которй содержится имя функции
2) существует переменная funct_param типа string в которой содержатся аргументы для этой функции
как мне найти эту функцию в теле программы и выполнить?
и еще: как можно получить результат её работы в другую переменную, например funct_result?
Всем привет. Подскажите плиз, как найти и выполнить функцию в теле программы, например:
1) существует переменная funct_name типа string в которй содержится имя функции
2) существует переменная funct_param типа string в которой содержатся аргументы для этой функции
как мне найти эту функцию в теле программы и выполнить?
и еще: как можно получить результат её работы в другую переменную, например funct_result?
Что-то я ничё не понял. Что ты хочешь сделать? Найти функцию в чужом exe файле и выполнить ее? Нафига? Если на то пошло, то для этого существует такая штука как библиотеки (dll) - вот из них и производится экспорт функции для выполнения.
Или, если не подходит, то изложи подробнее свою проблему.
Иными словами, мне нужен пример кода, который бы находил и выполнял функцию по имени в моей программе.
Я хочу найти и выполнить функцию в своей программе, зная её имя, которое хранится в переменной.
Иными словами, мне нужен пример кода, который бы находил и выполнял функцию по имени в моей программе.
Это зависит от языка программирования. И совсем не обязательно это возможно. Например, в PHP это реализуется так:
function abc($a, $b, $c) {
return $a+$b+$c;
}
echo @$function_name(1, 2, 3);
Всем привет. Подскажите плиз, как найти и выполнить функцию в теле программы, например:
1) существует переменная funct_name типа string в которй содержится имя функции
2) существует переменная funct_param типа string в которой содержатся аргументы для этой функции
как мне найти эту функцию в теле программы и выполнить?
и еще: как можно получить результат её работы в другую переменную, например funct_result?
1) описані ли прототипі данной функции?
2) является ли функция методом какого-то класса или нет?
3) на чем пишешь?
Если ті используешь не асмовій компилятор, то думаю єто будет нелегко - практически все компиляторі имеют особенность замангливать имена функций(не знаю правда все ли функции замангливаются.)
Если определяешь прототип, то по-идее задачка упрощается. Тогда, короче, нужно будет раскопать тестовій екзешник и посмотреть где єти прототипі определяются.
Я хочу найти и выполнить функцию в своей программе, зная её имя, которое хранится в переменной.
Иными словами, мне нужен пример кода, который бы находил и выполнял функцию по имени в моей программе.
Если это твой код, то его можно переписать таким образом, что бы использовать указатель на функцию, передавать его куда тебе нужно, вызывать в конце концов.
В делфях например есть специальный процедурный тип для хренения адресов функций и процедур.
TMyProcType = procedure (A,B: integer);
var
P: TMyProcType;
procedure SomeProc(A,B: integer);
begin
DoSomething;
end;
begin
P:=SomeProc; //инициализация
P (10,14); //вызов
end;
С функциями аналогично.
Можно ли как-то получить результат выполнения функции в другую переменную?
TMyProcType = procedure (A,B: integer); - тоесть для кажой процедуры нужно определять новый тип? А если у меня функции принимают разное количество параметров? Может есть какой-нибудь другой способ? Этакий eval() для делфи?
P.S. Модераторам: перенисите плиз треад в вопросы по делфи
Поискал в хелпе по делфи описание этого типа, ничего нет
Какраз в хэлпах всё написано хорошо. В индексе напиши: procedural type - найдёшь что искал :)
В делфи каждая функция имеет собственный процедурный тип (кламбур) - это то, как она объявлена.
TFirst = function (A,B: integer): integer; stdcall;
TSecond = function (A,B: integer): integer; register;
Эти два объявления будут совершенно различными (stdcall - передача параметров через стек register - через регистры).
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;
Кстати, в делфи различаются два рода укателей: указатель на обычную функцию и на функцию-член класса (как статическую, так и виртуальную).
То есть реализовать мою задумку на делфях невозможно? Может тогда асмовые инклуды решат задачу??
Какая задумка?
Если ты хочешь получить значение функции, адрес которой лежит в переменной процедурного типа, то читай внимательнее предыдущий пост (код).
Если ты хочешь получить адрес функции по её имени - то в Делфи этого в принципе сделать не возможно, не прибегая к дополнительному программированию (сохраниение имени и адреса в собственной хеш таблице и т.п. - но это уже изврат какой-то) - объектный код не содержит имён функций (за исключением секции exports).
Что вообще ты хочешь сделать?
А то допишешь новую команду, придёться кейс переписывать...
Буду наверно свою таблицу импорта делать... Тока вот думаеца мне что это еще более геморно чем кейс переписывать каждый раз:{
Пишу RAT сервер, и чтобы не парсить команды клиента кейсом, хочу один раз написать такую вот универсальную функцию:D
А то допишешь новую команду, придёться кейс переписывать...
Буду наверно свою таблицу импорта делать... Тока вот думаеца мне что это еще более геморно чем кейс переписывать каждый раз:{
Можно сделать так:
Каждая команда - некоторый класс.
При создании экземпляа класса происходит регистрация новой команды в твоей таблице команд. При получении команды ты ищешь связанную, с ней запись в таблице команд, а это и будет экземпляр класса этой команды и передаёшь в его метод, например Execute;
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 в соответствующей зарегистрированной команде.
Надеюсь идея вам ясна?
Если можешь, разжуй всё попобробнее
Общая идея понятна, но мне еще не приходилось так плотно работать с классами в делфи.
Если можешь, разжуй всё попобробнее
Вот рыба. что не понятно, стучи в асю 263-271-807
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;
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;
Предлагаю немного другой вариант(но из той же оперы :) ). Я вот подумал, нафига создавать каждый раз экземпляр команды, если там просто вызывается функция? Можно использовать просто классовые ссылки:
Тоже неплохо, но до определённого момента - вдруг нам понадобятся какие-то связывания при выполнении программы, например, команда управляет каким нибудь левым объектом.