5

実行時パッケージまたは共有メモリ DLL を使用せずに、ホスト アプリケーションとレコード タイプに関数/プロシージャが含まれる DLL モジュールとの間でレコード タイプを渡すことは可能ですか (Delphi 2006 以降)?

簡単にするために、Record 型には String フィールドが含まれていないと仮定しましょう (これにはもちろん Sharemem DLL が必要なため)。以下に例を示します。

TMyRecord = record
  Field1: Integer;
  Field2: Double;
  function DoSomething(AValue1: Integer; AValue2: Double): Boolean;
end;

簡単に言うと、ランタイム パッケージまたは共有メモリ DLL を使用せずに、TMyRecord の「インスタンス」をホスト アプリケーションと DLL の間で (どちらの方向でも) 渡し、ホスト EXE の両方から DoSomething 関数を実行できますか?そしてDLL?

4

2 に答える 2

7

それが機能するかどうかにかかわらず、私はそれをお勧めしません。インスタンスで操作するために DLL が必要TMyRecordな場合、最も安全なオプションは、代わりに DLL に単純な関数をエクスポートさせることです。

DLL:

type
  TMyRecord = record 
    Field1: Integer; 
    Field2: Double; 
  end; 

function DoSomething(var ARec: TMyRecord; AValue1: Integer; AValue2: Double): Boolean; stdcall;
begin
  ...
end;

exports
  DoSomething;

end.

アプリ:

type 
  TMyRecord = record  
    Field1: Integer;  
    Field2: Double;  
  end;  

function DoSomething(var ARec: TMyRecord; AValue1: Integer; AValue2: Double): Boolean; stdcall; external 'My.dll';

procedure DoSomethingInDll;
var
  Rec: TMyRecord;
  //...
begin 
  //...
  if DoSomething(Rec, 123, 123.45) then
  begin
    //...
  end else
  begin
    //...
  end;
  //...
end; 
于 2011-12-08T02:09:47.267 に答える
4

私があなたの質問を正しく理解したなら、あなたはそれをすることができます、これがそれをする一つの方法です:

testdll.dll

library TestDll;

uses
  SysUtils,
  Classes,
  uCommon in 'uCommon.pas';

{$R *.res}

procedure TakeMyFancyRecord(AMyFancyRecord: PMyFancyRecord); stdcall;
begin
  AMyFancyRecord^.DoSomething;
end;

exports
  TakeMyFancyRecord name 'TakeMyFancyRecord';

begin
end.

uCommon.pas <-アプリケーションとdllの両方で使用され、ファンシーレコードが定義されているユニット

unit uCommon;

interface

type
  PMyFancyRecord = ^TMyFancyRecord;
  TMyFancyRecord = record
    Field1: Integer;
    Field2: Double;
    procedure DoSomething;
  end;

implementation

uses
  Dialogs;

{ TMyFancyRecord }

procedure TMyFancyRecord.DoSomething;
begin
  ShowMessageFmt( 'Field1: %d'#$D#$A'Field2: %f', [ Field1, Field2 ] );
end;

end.

最後に、テストアプリケーション、ファイル->新規-> vclフォームアプリケーション、フォームにボタンをドロップし、uses句にuCommon.pasを含め、外部メソッドへの参照を追加します

procedure TakeMyFancyRecord(AMyFancyRecord: PMyFancyRecord); stdcall;
  external 'testdll.dll' name 'TakeMyFancyRecord';

ボタンのクリックイベントに、次のように追加します。

procedure TForm1.Button1Click(Sender: TObject);
var
  LMyFancyRecord: TMyFancyRecord;
begin
  LMyFancyRecord.Field1 := 2012;
  LMyFancyRecord.Field2 := Pi;
  TakeMyFancyRecord( @LMyFancyRecord );
end;

免責事項:

  • D2010で動作します。
  • 私のマシンでコンパイルします!

楽しい!


デビッド・ヘファーナンの編集

100%明確にするために、実行されるDoSomethingメソッドは、DLLで定義されたメソッドです。EXEで定義されたDoSomethingメソッドは、このコードでは実行されません。


于 2011-12-08T02:29:44.207 に答える