4

私は関数を持っています(Delphi 7、32ビットで書かれています):

関数GetVMTAddr(var C):整数;
始める
  結果:= Integer(C);
  試す
    PVmt(Result)^。SelfPtr:= PVmt(C)^。SelfPtr;
  それ外
    結果:= 0;
  終わり;
終わり;

これはVMTアドレスを返し(VMTだと思いますが、よくわかりません)、パラメーターがオブジェクトであるかどうかをチェックします(try...exceptこれは、非常に貧弱なソリューションです)。
2つの質問があります:
1)これは本当にVMTアドレスですか、それとも間違っていますか?
2)パラメータがオブジェクトであることを確認するためのより良い解決策はありますか?

4

1 に答える 1

10

引数Cに渡すものがクラス参照(別名メタクラス)である場合、引数はVMTアドレスを保持します。

関数でチェックインする条件は無意味です。メモリの特定の領域が書き込み可能かどうかをチェックし、それだけです。フィールドが値自体と等しいかどうかをチェックしている場合は、より近くなります。SelfPtrこのようなもの:

if PVmt(C).SelfPtr = C then
  Result := C;

あなたが尋ねていることは、数年前にここで尋ねられた質問と非常に似ています。そこでは、誰かが変数のタイプを検出する方法を知りたがっていました。その時説明したように、このコードを使用する必要があると思うところまで来たら、すでに問題を抱えています。推測する代わりに、クラス参照とオブジェクト参照のどちらがあるかを知ることができるように、戻って設計を変更してください。

本当に推測する必要がある場合は、JCLが提供する関数を使用してみてIsClassくださいIsObject。彼らはあなたのコードが使おうとしているのと同じ推測をしますが、彼らはそれを正しく行います。

于 2012-08-23T14:05:53.723 に答える