Re: Экспортные функции у приложения
От: Leonidze  
Дата: 04.08.07 13:52
Оценка: 1 (1) +1
Здравствуйте, DDS, Вы писали:

DDS>Подскажите в чем беда, пытаюсб из библиотеки вызвать экспортную функцию подключенного приложения (естесственно тоже моего). Пишу так:


DDS>В DLL:

DDS>
DDS>...
DDS>var
DDS>    fD: function:pchar; stdcall;
DDS>begin
DDS>  fD:=GetProcAddress( GetWindowWord(hwn,GWW_HINSTANCE) ,'GetFromAPP');
DDS>  if @fD<>nil then fD else ShowMessage('shit!');
DDS>end;
DDS>...
DDS>

DDS>В проге так:
DDS>
DDS>...
DDS>function GetFromAPP(p:pchar):pchar; stdcall; export;
DDS>begin
DDS>  ShowMessage('cool!');
DDS>end;

DDS>exports
DDS>  GetFromAPP index 1 name 'GetFromAPP';  
DDS>end.
DDS>

DDS>Дак вот все время один SHIT)) Не находит он функцию. HWND правильный, в проге этот код располагаю в тексте проекта, но и в тексте модуля формы (че как раз HWND) тоже пробовал. Не помогает. Подскажите...

Традиционно хэндл приложения (hInstance) получается через GetModuleHandle(nil); эта функция возвращает хэндл работающего кода, т.е. для dll это будет хэндл длл, для программы — хэндл программы. Кроме того, переменная hInstance — ссылающаяся на собственный хэндл кода afaik инициализируется RTL при старте.

Не совсем понял задачу — надо из длл вызвать какое приложение? которое dll загрузило? в этом случае удобнее предусмотреть функцию в DLL которая будет хранить (опять-же, в длл) указатель на объект/интерфейс/функцию основной программы. Т.е. схема примерно такая:
1. грузим длл
2. вызываем функцию длл передавая ей как параметр адрес функции/объекта/интерфейса программы
3. из длл по полученному указателю вызываются функции программы.
Такая схема удобна тем что нет необходимости динамически определять адреса функций в длл, достаточно определить интерфейс (в широком смысле слова) и передать один указатель.

Если надо вызывать функцию третьей программы, ее предварительно надо подгрузить.
Экспортные функции у приложения
От: DDS  
Дата: 03.08.07 13:04
Оценка:
Подскажите в чем беда, пытаюсб из библиотеки вызвать экспортную функцию подключенного приложения (естесственно тоже моего). Пишу так:

В DLL:
...
var
    fD: function:pchar; stdcall;
begin
  fD:=GetProcAddress( GetWindowWord(hwn,GWW_HINSTANCE) ,'GetFromAPP');
  if @fD<>nil then fD else ShowMessage('shit!');
end;
...

В проге так:
...
function GetFromAPP(p:pchar):pchar; stdcall; export;
begin
  ShowMessage('cool!');
end;

exports
  GetFromAPP index 1 name 'GetFromAPP';  
end.

Дак вот все время один SHIT)) Не находит он функцию. HWND правильный, в проге этот код располагаю в тексте проекта, но и в тексте модуля формы (че как раз HWND) тоже пробовал. Не помогает. Подскажите...
Re: Экспортные функции у приложения
От: sof.bix Россия http://byterix.net
Дата: 03.08.07 13:23
Оценка:
Здравствуйте, DDS, Вы писали:

DDS>Подскажите в чем беда, пытаюсб из библиотеки вызвать экспортную функцию подключенного приложения (естесственно тоже моего). Пишу так:


DDS>В DLL:

DDS>
DDS>...
DDS>var
DDS>    fD: function:pchar; stdcall;
DDS>begin
DDS>  fD:=GetProcAddress( GetWindowWord(hwn,GWW_HINSTANCE) ,'GetFromAPP');
DDS>  if @fD<>nil then fD else ShowMessage('shit!');
DDS>end;
DDS>...
DDS>


Странно, а я всегда делал так:

fD:= @GetProcAddress( 0 ,'GetFromAPP');


И у меня сробатывало, поскольку Load<чегото там чтобы получить Handle приложения>('имя_приложения.exe'); возвращал 0, и это не потому что он не срабатывал
Re: Экспортные функции у приложения
От: Аноним  
Дата: 08.08.07 06:56
Оценка:
Насколько я помню в Дельфи нельзя делать экспорт функций из EXE.
Там релокация работает неверно.
Re[2]: Экспортные функции у приложения
От: DarkMaster Украина http://www.bdslib.at.ua
Дата: 08.08.07 07:58
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Насколько я помню в Дельфи нельзя делать экспорт функций из EXE.

А>Там релокация работает неверно.

Ага, как же... Работает нормально. Вот примерный код. Могут быть синтаксические ошибки, но смысл, надеюсь, будет понятен.



//------------------------
// главный EXE
//-----------------------
type
    THelloProc=procedure; stdcall;

// эту процедуру будем вызывать из библиотеки
procedure Hello; stdcall;
begin
 ShowMessage('Hello!');
end;
// это для теста вызова функции приложения из ДЛЛ
procedure TestHello; 
var FHandle:THandle;
    P:THelloProc;  
begin
 FHandle:=LoadLibrary('TestHelloLib');
 if FHandle<>0 then
    begin
      @P:=GetProcAddress(FHandle,'Test');
      if @P<>nil then P;
      FreeLibrary(FHandle);
    end;
end;
// собственно тест
procedure TForm1.OnButtonClick(Sender:TObject);
begin
  TestHello;
end;

exports 
  Hello;
end.
//--------------------
// модуль интерфейса приложение <-> библиотека
//--------------------
unit MainExeExports;
interface
procedure Hello; stdcall;
implementation
procedure Hello; external 'MyMainExe.exe' name 'Hello';
end;
//--------------------
// библиотека
//--------------------
library TestHelloLib;
Uses MainExeExports;

procedure Test; stdcall;
begin
  Hello;
end;

exports
  Test;
end.
WBR, Dmitry Beloshistov AKA [-=BDS=-]
Re[2]: Экспортные функции у приложения
От: sof.bix Россия http://byterix.net
Дата: 08.08.07 12:44
Оценка:
Здравствуйте, Leonidze, Вы писали:

L>Традиционно хэндл приложения (hInstance) получается через GetModuleHandle(nil); эта функция возвращает хэндл работающего кода, т.е. для dll это будет хэндл длл, для программы — хэндл программы. Кроме того, переменная hInstance — ссылающаяся на собственный хэндл кода afaik инициализируется RTL при старте.


L>Не совсем понял задачу — надо из длл вызвать какое приложение? которое dll загрузило? в этом случае удобнее предусмотреть функцию в DLL которая будет хранить (опять-же, в длл) указатель на объект/интерфейс/функцию основной программы. Т.е. схема примерно такая:

L>1. грузим длл
L>2. вызываем функцию длл передавая ей как параметр адрес функции/объекта/интерфейса программы
L>3. из длл по полученному указателю вызываются функции программы.
L>Такая схема удобна тем что нет необходимости динамически определять адреса функций в длл, достаточно определить интерфейс (в широком смысле слова) и передать один указатель.

Последний способ не плох, но придется либо хранить глобальный "адрес функции/объекта/интерфейса программы" или таскать его при каждом вызове в контексте...

А вот GetModuleHandle(nil); в DLL как раз возвращает хендл EXE вроди
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.