クラス内の関数を関数テーブルにして、それをコールするときの注意点

解決


カーネル・ダンサーズ  2004-11-22 08:25:28  No: 11855

「無効なポインタ操作」が出てしまいます。

type
  TFunc = function(): integer; of object;

type
  PStateTbl = ^TStateTbl;
  TStateTbl = record
  pFunc  :TFunc;
end;

type
  TState = array of TStateTbl;

と、宣言し、クラス内でpublic宣言している関数を
関数テーブルにしています。

type
  TModel = class(TObject)
  private
  public
    constructor Create;
    destructor Destroy; override;
    function SetTbl(var Tbl:TState): integer;

    function func01: integer;
    function func02: integer;
    function func03: integer;
end;

function TModel.SetTbl(var Tbl: TState): integer;
var
  i       : integer;
  nTblSize: integer;
begin
  i := 0;
  nTblSize := 4;  //テーブル数
  SetLength(Tbl, nTblSize);

  Tbl[i].pFunc  := nil;
  Inc(i);

  Tbl[i].pFunc  := func01;
  Inc(i);
  :
  :
end;

こんな感じです。
そして、別のスレッドで以下のように宣言して

FModelType: TObject;
FStateTbl : TState;

以下のように生成、テーブルを作成しています。
FModelType := TModel.Create;
TModel(FModelType).SetTbl(FStateTbl);

使うときは、
State := FStateTbl[1];
FFuncExec := State.pFunc;
nRes := FFuncExec();

などというように使っています。
どこか問題ありますでしょうか?

どこかで「無効なポインタ操作」というエラーが出てしまいます。
どこが問題でこのようなエラーが出るのか知識が足りなく追うことができません。
以前は、この関数テーブルをクラス内のpublic関数ではなく、
グローバル?関数で作っていて、そのときはエラーがでなかったので、
問題はこの関数テーブル辺りかなと踏んでいるのですが先に進めなく
困っています。

どなたかご教授お願い致します。

やりたいことは、
・スレッド内から関数テーブルをコールしたい。
・関数テーブルにする関数は、とあるクラス内の関数。
・この、とあるクラスというのは、複数種類があって、
  入れ替えることができる。
  →Aクラスの関数とBクラスの関数を入れ替えることができる。

説明下手で申し訳ないのですがご理解いただけますでしょうか・・・


カーネル・ダンサーズ  2004-11-22 19:03:39  No: 11856

よくわかりませんが、メッセージを複数のフォームに送信するのをやめて、
1つのフォームだけに送信するようにしたらエラーが出なくなりました・・・。
上の質問とは違う部分だったのかもしれません。が、
根本的な解決はしていません・・・。

「無効なポインタ操作」
これが出たとき、みなさんはどうやって原因を突きとめるのでしょうか・・・。
僕の場合、
「無効なポインタ操作」
「で、それはどこだ?」
となってしまいます・・・。
特に、クローズ「×」をクリックした後なんかに出てしまうと、
ブレーク貼ってもうまいこと追えないし・・・。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加