Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Dll + ссылка на объект в вызывающей программе


Автор: Вася К. 17.3.2006, 10:11
Здраствуйте!

Можно ли при инициализации dll, в блоке begin ... end получить указатель на объект в вызывающей программе?

Спасибо!

Автор: Демо 17.3.2006, 10:23
В момент инициализации библиотеки она еще не имеет доступа к адресному пространству вызвавшего процесса. Мне так кажется.

Автор: _hunter 17.3.2006, 11:36
а не проще ли этот указатель ей передать?

Автор: Демо 17.3.2006, 11:38
Цитата(_hunter @ 17.3.2006, 11:36 Найти цитируемый пост)
а не проще ли этот указатель ей передать?


Передать-то только после инициализации можно;)

Автор: _hunter 17.3.2006, 11:58
ну и отлично.
в DllMain он всеравно нафик не нужен smile

Автор: Alexeis 17.3.2006, 12:14
Можно попробовать так при инициализации dll, dll загрузит другую dll, которая просмотрит все процессы и проверит кто загрузил первую. Правда неизвестно будет ли первая считаться уже загруженной...

Автор: Демо 17.3.2006, 12:33
Цитата(Вася К. @ 17.3.2006, 10:11 Найти цитируемый пост)
Можно ли при инициализации dll, в блоке begin ... end


Получить можно, но что это даст?

Автор: Alexeis 17.3.2006, 12:52
Вася К., лучше поведай в чем задача может есть альтернативные пути решения.

Автор: bems 17.3.2006, 14:10
Цитата(Демо @ 17.3.2006, 10:23 Найти цитируемый пост)
В момент инициализации библиотеки она еще не имеет доступа к адресному пространству вызвавшего процесса. Мне так кажется.

имеет
Цитата(alexeis1 @ 17.3.2006, 12:14 Найти цитируемый пост)
Можно попробовать так при инициализации dll, dll загрузит другую dll, которая просмотрит все процессы и проверит кто загрузил первую. Правда неизвестно будет ли первая считаться уже загруженной...
проще уже файлмаппинг расшарить по имени. Или tls.

Автор: Вася К. 17.3.2006, 14:23
В Dll сидят некоторые процедуры для работы с базой Interbase. И в ней для работы сидит один глобальный IBQuery, IBTransaction , и чтобы не создовать лишний коннект к базе, я использую IBDatabase приложения. Сейчас я передаю указатель на IBDatabase после загрузки dll с помощью дополнительной процедуру. Вот подумал, может можно сразу назначить IBDatabase для IBQuery и т.д...

Автор: bems 17.3.2006, 14:25
Ща пример налабаю...

Автор: bems 17.3.2006, 16:33
Код

unit SharedConsts;

interface
uses windows;
type pObj=^TObject;
const FMname='kjrvfvuthvu_tfjudmwskxc8548655__934jd8fddjslk_zsdm94v4kre';
      FMSize=64*1024;
      shdObject=0;shdAnotherSharedData=4;//и тд если надо
var h:THANDLE;view:pointer;

function GetSharedData(offset:DWORD):pointer;

implementation

function GetSharedData(offset:DWORD):pointer;
begin
result:=pointer(DWORD(view)+offset)
end;

end.



Код

program prog;
uses
  windows,SharedConsts;
var lib:THANDLE;
    YourCoolObject:TObject;
begin
YourCoolObject:=TObject.Create;
h:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,FMSize,FMname);
view:=MapViewOfFile(h,FILE_MAP_WRITE,0,0,FMSize);
if assigned(view) then pObj(GetSharedData(shdObject))^:=YourCoolObject;
lib:=LoadLibrary('lib.dll');
UnmapViewOfFile(view);
CloseHandle(h);
if lib=0 then MessageBox(0,'!',nil,0)
         else begin
              //используешь библиотеку
              FreeLibrary(lib);
              YourCoolObject.Free;
              end;
end.


Код

library lib;
uses windows,SharedConsts;
var SomeExternalObject:TObject;   s:string;
begin
view:=nil;
h:=OpenFileMapping(FILE_MAP_WRITE,false,FMname);
view:=MapViewOfFile(h,FILE_MAP_WRITE,0,0,FMSize);
ExitCode:=integer(not assigned(view));
if not boolean(ExitCode) then begin
                              SomeExternalObject:=PObj(GetSharedData(shdObject))^;
                              UnmapViewOfFile(view);
                              CloseHandle(h);

                              s:=SomeExternalObject.ClassName;             //тут используешь
                              MessageBox(0,PChar(s),'Класс объекта',MB_OK);//свой объект
                              end;
end.

Автор: Girder 17.3.2006, 18:33
Код
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var h:DWord;
    s:array [0..10] of Char;
    i:DWord;
begin
 asm
  mov i,esp
 end;
 i:=i-$2000;
 PDWord(i)^:=DWord(@s);
 PDWord(i-4)^:=$33771122;
 PDWord(i-8)^:=$11221122;
 FillChar(s,SizeOf(s),#0);
 h:=LoadLibrary('mDLL.dll');
 if h<>0 then
  begin
   caption:=PChar(@s);
   FreeLibrary(h);
  end;
end;

end.


Код

library mDLL;

uses
  Windows;

var i:PDWord;
    p:PAnsiChar;

begin
 asm
  mov i,esp
 end;
 try
  repeat
   while (i^<>$33771122) do dec(i);
   dec(i);
  until (i^=$11221122);
  inc(i);inc(i);
  p:=Pointer(i^);
  p^:='Г';
  inc(p);
  p^:='ы';
  inc(p);
  p^:=#0;
 finally
  //Не вышло :)
 end;
end.


PS: smile

Автор: bems 17.3.2006, 19:36
Girder, ась?

Нет, серьезно, поподробнее?

особенно про это
Цитата(Girder @ 17.3.2006, 18:33 Найти цитируемый пост)
asm
  mov i,esp
end;
i:=i-$2000;
PDWord(i)^:=DWord(@s);
PDWord(i-4)^:=$33771122;
PDWord(i-8)^:=$11221122;


и это

Цитата(Girder @ 17.3.2006, 18:33 Найти цитируемый пост)
  repeat
  while (i^<>$33771122) do dec(i);
  dec(i);
  until (i^=$11221122);
  inc(i);inc(i);
  p:=Pointer(i^);
  p^:='Г';
  inc(p);
  p^:='ы';
  inc(p);
  p^:=#0;



M
Girder
А что тут объяснять?
Проще только 2+2 :) !

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)