0

BTMemoryModuleを使用してDLLをプロセスに挿入します。メイン/親プロセスは関数/プロシージャを呼び出すことができますが、他の方法はどうですか?dllはメイン/親プロセスから変数を読み取ったり取得したりできますか、または関数を呼び出すことができますか?

ご協力ありがとうございました。

編集:DLL

library mydll; // DLL obviously...
uses windows;

procedure Test
begin
 // I need a string/integer/pointer from ParentProcess
end

exports
Test;

begin
 // I need a string/integer/pointer from ParentProcess. (if possible). 
end.

プログラム:

program myprogram
uses
...
var
 M : PBTMemoryModule;
begin
 BTMemoryLoadLibary (pointer, pointerlength);
 @myMaintest    := BTMemoryGetProcAddress(M, 'Test');
 ...
end;
4

3 に答える 3

4

まず第一に、それは通常注射と呼ばれるものではないようです。これは、ファイルではなくメモリからではありますが、単なるモジュールのロードです。

DLLがEXEから関数をインポートする方法については、EXEがDLLからインポートする場合とまったく同じ方法で実行してください。

  1. exportsEXEがエクスポートする関数を一覧表示するために使用します。
  2. を呼び出して、EXEのモジュールハンドルを取得しますGetModuleHandle(nil)
  3. そのモジュールハンドルをに渡して、GetProcAddress関数をインポートします。

DLLパターンにリンクするより一般的なEXEとの唯一の違いは、GetModuleHandleではなくを使用することですLoadLibrary。これは、EXEがすでにロードされている必要があるため、モジュールのロードを要求するのではなく、モジュールハンドルを要求するだけで済みます。

このようにするのはかなり珍しいことだとコメントします。通常、EXEはDLLを呼び出し、DLLに必要な情報をすべて渡します。その情報には、DLLがホストEXEを照会できるようにするコールバック関数やインターフェイスなどが含まれる可能性があります。

于 2012-07-20T08:04:21.867 に答える
2

子モジュール(DLL)が親アプリケーションのデータ構造と機能を知っている場合、これは可能です。これらのデータと関数は、親側で使用できるようにする必要があります。

于 2012-07-20T06:07:09.020 に答える
0

これは、私のコメントをDavidの答えにさらに拡張するためのものです。


DLL側:

  1. DLLにInitプロシージャを追加します
  2. エクスポートします。
  3. 必要に応じて必要なtype/var宣言を追加します

スニペットコード:

library TheDLL;

...

var
  OwnerAPP: HMODULE; // To be initialized by a call of the exported procedure Init from the EXE

...

type
  TTestCallfromExe = procedure(f_Text: PAnsiChar); stdcall;

var
  OwnerAPP: LongInt;
  l_TestCallfromExe: TTestCallfromExe;

procedure Init(Owner: HMODULE);
begin
  OwnerAPP := Owner;
end;

...

exports
  Init, // This is it and the others exports follow
  ...

TestCallfromExeの呼び出しは、DLLのエクスポートされた関数/プロシージャへの通常の呼び出しと同じように実行されます。OwnerAPPが正しく初期化されている限り、OPの要件に従って、DLLのエクスポートされた関数の本体で呼び出しを行うことができます。


EXE側:

必要に応じて、すべてのプロシージャ/関数(DLLから呼び出される)をエクスポートします。もちろん、それぞれを実装する必要があります。

program TheEXE;

uses
  ...
  MyExportImplementation; // Refence to implementatio unit

...

exports
  TestCallfromExe, // This is it
  ...

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

実装の詳細の例:

unit MyExportImplementation;

interface

...

procedure TestCallfromExe(f_Text: PAnsiChar); stdcall;

implementation

...

procedure TestCallfromExe(f_Text: PAnsiChar); stdcall;
begin
  MessageBoxA(0, f_Text, 'Exe Dialog Ansi (stdcall)', 0);
end;

...

end.

すべてを一緒に入れて:

これは、DemoDLL(BTMemoryから)サンプルに基づいており、たとえば、TheEXE.dprプロジェクトのMainFormユニットに実装されます。

procedure TForm1.BtnCAllClick(Sender: TObject);
var
  l_Init: procedure(Owner: HMODULE);
begin
  m_DllHandle := LoadLibrary('TheDLL.dll');
  try
    if m_DllHandle = 0 then
      Abort;

    @l_Init := GetProcAddress(m_DllHandle, 'Init');  // <<<
    if @l_Init = nil then
      Abort;

    // Fetch the remainding exported function(s)/procedure(s) adresses

    l_Init(HInstance); // <<<  Hand EXE's HInstance over to the DLL

    // Call exported function(s)/procedure(s) accordingly
  except
    Showmessage('An error occured while loading the dll');
  end;

  if m_DllHandle <> 0 then
    FreeLibrary(m_DllHandle)
end;

Nota Bene:

BTMemoryでもテストしましたが、動作します。

于 2012-07-20T11:32:58.913 に答える