Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2006.01.01;
Скачать: [xml.tar.bz2];

Вниз

Как получить адрес процедур собственной программы (по названию п)   Найти похожие ветки 

 
AllDontFire   (2005-10-29 15:24) [0]

Пробовал GetProcAddress, но, насколько я понял, так нельзя, это только для Dll?


 
begin...end ©   (2005-10-29 15:48) [1]

> AllDontFire   (29.10.05 15:24)

Это возможно и для EXE, но нужные подпрограммы нужно включить в список exports.


 
wp2   (2005-10-29 15:52) [2]

А если попробовать @


 
raiks   (2005-10-29 19:05) [3]

procedure DoSomething;
begin

end;

var p: Pointer;
begin
 p:=@DoSomething;
 ShowMessage("Адрес DoSomething: " + IntToStr(Cardinal(p)));
end;


 
AllDontFire   (2005-10-29 22:15) [4]

raiks,
p:=@DoSomething - -это понятно.
Но мне нужно найти адрес, передавая символьное название процедуры как в
GetProcAddress.


 
wp2   (2005-10-30 01:39) [5]

Удалено модератором


 
raiks   (2005-10-30 02:29) [6]

Объясните конкретнее, для чего вам это нужно. Почему нельзя использовать приведенный пример?


 
Джо ©   (2005-10-30 02:37) [7]


>  [4] AllDontFire   (29.10.05 22:15)

Разумумный ответ см.  [1] begin...end ©   (29.10.05 15:48)

Другой подход - сделать процуры published-методами какого-нибудь класса, скомпилированным с директовой {$M+}. Тогда можно искать методы по имени.

Непонятно только, зачем это нужно? Может, если объяснить конкретную задачу, найдется более оптимальное решение.


 
Джо ©   (2005-10-30 02:01) [8]

Делать мне, наверное, нечего.

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

Подход с получением адреса экспортируемой функции.

program Project2;

{$APPTYPE CONSOLE}

uses
 Windows,
 SysUtils;

// эта процедура экспортируется
procedure DoSomething;
begin
 WriteLn ("DoSomething called.");
end;

// эта процедура экспортируется
procedure DoSomethingElse;
begin
 WriteLn ("DoSomethingElse called.");
end;

// а эта процедура НЕ экспортируется
procedure YouCannotCallMe;
begin
 WriteLn ("You should not see this message.");
end;

// экспортируем нужные функции
exports
 DoSomething,
 DoSomethingElse;

var
 ProcName: string;
 Proc: procedure;

begin
 ProcName := ParamStr(1);

 if ProcName = "" then
 begin
   WriteLn ("Specify a procedure name");
   Exit;
 end;

 proc := GetProcAddress(0,PChar(ProcName));
 if Assigned(Proc) then
   Proc()
 else
   WriteLn ("Procedure ",ProcName," not found in executable.");

 ReadLn;
end.

---
Подход с получением адреса published-метода класса.

program Project2;

{$APPTYPE CONSOLE}

uses
 SysUtils,
 TypInfo;

type

 TCommander = class
 public
   procedure YouCannotCallMe;
 published
   procedure DoSomething;
   procedure DoSomethingElse;
 end;

{ TCommander }

procedure TCommander.DoSomethingElse;
begin
 WriteLn ("DoSomethingElse called.");
end;

procedure TCommander.DoSomething;
begin
 WriteLn ("DoSomething called.");
end;

procedure TCommander.YouCannotCallMe;
begin
 WriteLn ("You should not see this message.");
end;

var
 ProcName: string;
 Proc: procedure;
 Commander: TCommander;

begin
 ProcName := ParamStr(1);

 if ProcName = "" then
 begin
   WriteLn ("Specify a procedure name");
   Exit;
 end;

 Commander := TCommander.Create;
 try
   Proc := Commander.MethodAddress (ProcName);
   if Assigned (Proc) then
     Proc ()
   else
     WriteLn ("Unknown command requested.");
 finally
   Commander.Free;
 end;

 ReadLn;
end.


П.С. Надеюсь, пригодится.

И -- я наврал насчет директивы {$M+}, сейчас вожусь с RTTI и немного заработался, видимо :(


 
Джо ©   (2005-10-30 02:34) [9]

Мда... спешка к добру не приводит. Исправления во второй пример, позорные:

var
...
Proc: procedure of object;
...
   TMethod(Proc).Code := Commander.MethodAddress (ProcName);
   TMethod(Proc).Data := Commander;


 
AllDontFire   (2005-10-30 11:23) [10]

Спасибо, всё понятно.
Ну это нужно, например, когда, в зависимости от какого-либо входного параметра, необходимо запустить опр. процедуру. Можно конечно выйти из положения через IF, но, а если много вариантов входных параметров, то и "Ифов" будет много, а это не удобно я думаю.


 
raiks   (2005-10-30 13:39) [11]

Джо

Ради интереса опробовал 1-й ваш пример. Работает :) Потом решил проделать то же самое с другим *.exe, в раздел exports которого добавлена соответствующая строка. Файл нормально загрузился с помощью LoadLibrary, адрес процедуры DoSomething тоже нашелся, но при попытке вызвать ее вылезло неизбывное сообщение об Access Violation. Я так понимаю, это связано с атрибутами доступа к памяти? Можно ли это исправить?

-----------Project1.exe------------

program Project1;
uses Windows;

procedure DoSomething;
begin
 MessageBox(0, "Hello from DoSomething()", nil, MB_ICONWARNING);
end;

exports
 DoSomething;

begin
end.

-----------Project2.exe------------

var
 hLib: THandle;
 DoSmth: procedure;
begin
 hLib:=LoadLibrary("f:\project1.exe");
 if hLib<>0 then
   begin
     MessageBox(0, "Module Project1 was loaded!", nil, MB_ICONWARNING);
     @DoSmth:=GetProcAddress(hLib, "DoSomething");
     if @DoSmth<>nil then
       begin
         MessageBox(0, "Procedure DoSomething() was found!", nil,   MB_ICONWARNING);
         DoSmth;
      end;
     FreeLibrary(hLib);
   end;
end;


 
Digitman ©   (2005-10-31 10:17) [12]


> raiks   (30.10.05 13:39) [11]


> связано с атрибутами доступа к памяти?


нет, это связано с совершенно иным - с обработкой загрузчиком таблицы релокации и инициализацией pe-модуля


 
Polevi ©   (2005-10-31 10:47) [13]

можно сделать через FindClass



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2006.01.01;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.01 c
6-1127233878
Galiaf
2005-09-20 20:31
2006.01.01
Сокеты "склеивают" сообщения!


14-1133945351
Stilgar
2005-12-07 11:49
2006.01.01
Что вы думаете о конце света?


2-1134419119
гость2
2005-12-12 23:25
2006.01.01
thotkey -> string


2-1134458053
Kot
2005-12-13 10:14
2006.01.01
Открыть папку нажатием кнопки


2-1133960986
Plotnick
2005-12-07 16:09
2006.01.01
Как сделать приличную тень под окном





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский