喫茶XRAYトップページ

[スレッド全体
]

[11931] DLL内の関数とフォームの関数の実行返信 削除
2018/6/14 (木) 07:41:42 Mr.XRAY
[DLL にて except 使用]
http://madia.world.coocan.jp/cgi-bin/DelphiBBS/wwwlng.cgi?print+201806/18060002.txt

abc 2018/06/14(木) 05:58:32

のコードを解読すると以下のようなことのようです.
何とも言えない,面白いのか,変なのか,摩訶不思議なと言うか... (^^:

DLL を使用する側のプロジェクトのコード

unit Unit1;

interface

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

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

procedure FormProcA(AText: PChar);stdcall;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure DLL_funcA(AProc: TFarProc); stdcall; external 'Test_DLL.dll';

//-----------------------------------------------------------------------------
//  DLL内の関数を実行
//  引数はこのユニット内で定義している関数
//  つまり,DLLからこのフォームの関数を実行している
//-----------------------------------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
begin
  DLL_funcA(@FormProcA);
end;

//-----------------------------------------------------------------------------
//  この関数をDLLから実行する
//-----------------------------------------------------------------------------
procedure FormProcA(AText: PChar);
begin
  Form1.Memo1.Lines.Add(AText);
end;

end.


DLL のコード

library Test_DLL;

uses
  Windows;

type
  TMyFuncType =  procedure (AText: PChar);stdcall;

var
  FormProcA : TMyFuncType;

//-----------------------------------------------------------------------------
procedure DLL_funcA(AProc: TFarProc); stdcall;
begin
  @FormProcA := AProc;
  FormProcA('*** ABC ***');
end;

//-----------------------------------------------------------------------------
exports
  DLL_funcA;

end.


実行結果です.
実行環境は Windows 7 U64(SP1) + Delphi XE5(UP2) Pro です.
質問された方が書いている LogWriteProc2 は無理です.
何故なら関数内関数になっています.
もちろん,expect は全く関係ありませんです.
もちろん,バグでもありません.

これが朝起きて最初の作業.おそまつ ! (笑)



[11933] Re:DLL内の関数とフォームの関数の実行返信 削除
2018/6/14 (木) 12:41:52 Mr.XRAY
> 質問された方が書いている LogWriteProc2 は無理です.
> 何故なら関数内関数になっています.
> もちろん,expect は全く関係ありませんです.


これなんですが,DLL を使用する側を以下とします.

procedure TForm1.Button2Click(Sender: TObject);

  //この関数はinterface部で定義(関数宣言を)していない
  //関数内関数はinterface部で定義(関数宣言)できない
  procedure LogWriteProc2(AText: PWideChar); stdcall
  begin
    Memo1.Lines.Add(AText);
    Memo1.Lines.Add('LogWriteProc2');
  end;

begin
  DLL_funcB(@LogWriteProc2);
end;

そして DLL 側の DLL_funcB を以下のようにします.
もちろん DLL_funcB は exports 部に追加して,var にも次のように追加しておきます.

var
  FormProcA : TMyFuncType;
  LogWriteProc2 : TMyFuncType;

procedure DLL_funcB(AProc: TFarProc); stdcall;
begin
  @LogWriteProc2 := AProc;
  LogWriteProc2('*** DDD ***');
end;

実行するとできてしまうんですね (下図が実行結果).知りませんでした.
で DLL_funcB を以下にすると例外が発生します.当然と言えば当然なのですが.
これが質問された方が言う「バグ」ですね.
自分が意図しない動作をするのは全て「バク」? 好きです,こういう姿勢 (笑)

procedure DLL_funcB(AProc: TFarProc); stdcall;
begin
  try
    @LogWriteProc2 := AProc;
    LogWriteProc2('*** DDD ***');
  except
  end;
end;



[11934] Re2:DLL内の関数とフォームの関数の実行返信 削除
2018/6/14 (木) 12:57:42 Mr.XRAY
> 実行するとできてしまうんですね (下図が実行結果).知りませんでした.

いや,正直驚きました !!


[11935] 良い子は真似しない方がいいと思う返信 削除
2018/6/14 (木) 13:10:45 Mr.XRAY
DLL というのは基本的に各種のプログラム言語から共通して利用するのが目的です.
ただし,特定の言語用として作成することもありますが,
独立して利用できるようにするのがよろしいかと.

しかしながら,今回の質問の方のは特定のユニット専用の DLL となります.
つまり,わさわざ DLL にする意味がありません.
こういう使い方があるのかは分かりませんが,
基本的にはやらない方がいいと思います.

ただし,質問された方の意図が不明なので,これはあくまでも私見です.


[11936] 関数内関数返信 削除
2018/6/14 (木) 14:03:57 Mr.XRAY
今回の場合はプロシージャ内プロシージャーとでも言うのかも知れませんが,
関数内関数は,その関数内だけで使用するためのものです.
それをその関数以外で使用するのであれば,関数内関数にする意味がありません.
と思います.


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82