関数の名前だけを引数に渡して、関数を実行したい


WWW  2009-04-03 09:46:04  No: 33867  IP: 192.*.*.*

すいません、私には難しいので教えてください。

関数  Exampleがあったとして、その引数に関数の名前だけを渡します。

Example(実行したい関数名);
 .
 .
 .

Procedure THoge1.Example(Name: THoge2);
begin
  Tzikkou.Nmae;  ←ここでTzikkouの中の関数を実行
end;

とにかくExampleに入るたびに関数の名前を受け取って、Tzikkkoの中に
あるそれぞれの関数を判断して実行していきたいのですが。
やりかたもよくわからないですし、ほかにいい方法などありますか?
よろしくお願いします。

編集 削除
Manbon  2009-04-03 10:28:22  No: 33868  IP: 192.*.*.*

いまいち分からないのですが、文字列で判断というのはだめですか?

procedure THoge1.Example(Name: string);
begin
  if Name = 'AAA' then Tzikkou.AAA else
  if Name = 'BBB' then Tzikkou.BBB else
  if Name = 'CCC' then Tzikkou.CCC else
                       Tzikkou.ZZZ;
end;

編集 削除
WWW  2009-04-03 10:47:45  No: 33869  IP: 192.*.*.*

Manbonさん

回答ありがとうございます。

そうです、確かに文字列判断で済むことですが、Tzikkou.Nmaeを一行でなんとかならないかなと思ったので聞きました。

実際にNameの種類がかなり多くなってしまえば、条件文がそれだけ増えてしまうので、何か良い方法はないかと…

編集 削除
KHE00221  2009-04-03 10:59:53  No: 33870  IP: 192.*.*.*

TZikkou = class(TComponent)
  public
    procedure Execute1;
    procedure Execute2(Sender: TObject);
  end;


procedure TZikkou.Execute1;
begin
    MessageBox(0,'Execute1','',0);
    Exit;
end;

procedure TZikkou.Execute2(Sender: TObject);
begin
    MessageBox(0,'Execute2','',0);
    Exit;
end;

type
  TAProc  = procedure of object;

procedure TForm1.Example(X:Pointer);
var
    Method: TMethod;
begin
    Method.Data := TZikkou;
    Method.Code := X;
    TAProc(Method);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
    Example(@TZikkou.Execute1);
end;

Createしなくても実行できたりするけど・・・

編集 削除
にしの  2009-04-03 12:27:55  No: 33871  IP: 192.*.*.*

Exportして、LoadLibraryで関数名を指定すればいけるかと思います。

編集 削除
ttt  2009-04-03 14:05:53  No: 33872  IP: 192.*.*.*

名前(文字列)にこだわる必要がなければ、
手続き型(いわゆる関数ポインタ)を使う方法もありますけど。

たとえば、実行したい関数が次の2つだとします。
function AAA(n: Integer);
function BBB(n: Integer);

この場合、次のように手続き型の変数を用意して、値を設定します。
type PMyFunction = function(n: Integer); // 手続き型を定義
var hoge: PMyFunction; // その型の変数を用意
...
if 条件 then hoge := AAA else hoge := BBB; // 呼び出したい関数へのポインタを変数に入れておく
...
Example(hoge); // 実行したい関数を渡す

で、実行する関数の方はこんな感じ。
procedure THoge1.Example(f: PMyFunction);
begin
  f(1); // 引数を指定して関数を呼び出す
end;

引数をとらない場合とか、クラスのメンバだったらどうするのか
といったあたりはヘルプの「手続き型」を参照してください。

編集 削除
ttt  2009-04-03 20:37:04  No: 33873  IP: 192.*.*.*

functionなのに関数値忘れていたけど、その辺は適宜読み替えて……

ちなみに、publishedなメソッドに限ればMethodAddressで名前から逆引きできるみたいですね。
使ったことないけどこんな感じになるのかな。

procedure THoge1.Execute(obj: TObject; const name: String);
var f: procedure of object;
begin
  f := obj.MethodAddress(name);
  if Assigned(f) // 一応ポインタがとれたか確認してから
    f; // 呼び出す
end;

編集 削除
KHE00221  2009-04-04 09:28:40  No: 33874  IP: 192.*.*.*

>procedure TForm1.Example(X:Pointer);
>var
>    Method: TMethod;
>begin
>    Method.Data := TZikkou;
>    Method.Code := X;
>    TAProc(Method);
>end;

こんなことしなくても

type
    TAProc  = procedure of object;

procedure Execute(AProc: TAProc);
begin
    AProc;
end;

procedure TForm4.Button3Click(Sender: TObject);
begin
    Execute(Button2.Click);
end;

これだけでいいのか・・

編集 削除
関数ポインタ  2009-04-04 16:57:34  No: 33875  IP: 192.*.*.*

関数ポインタをキックするだけでいいんでは?
文字列で指定したいなら、対象文字列と関数ポインタを配列に格納して
forで回して検索すればいいんでない??

編集 削除