この質問は前の質問に基づいていますが、それは参考までにです。
私はそれをうまく動かすことができました、しかし私は私にははっきりしない何かを見つけました、それで誰かが次の振る舞いを説明することができればそれは素晴らしいでしょう。
私は次のクラスを持っています:
type
TMyObj = class
published
procedure testex(const s: string; const i: integer);
end;
procedure TMyObj.testex(const s: string; const i: integer);
begin
ShowMessage(s + IntToStr(i));
end;
および次の2つの手順:
procedure CallObjMethWorking(AMethod: TMethod; const AStrValue: string; const AIntValue: Integer);
begin
asm
PUSH DWORD PTR AIntValue;
PUSH DWORD PTR AStrValue;
CALL AMethod.Code;
end;
end;
procedure CallObjMethNOTWorking(AInstance, ACode: Pointer; const AStrValue: string; const AIntValue: Integer);
begin
asm
MOV EAX, AInstance;
PUSH DWORD PTR AIntValue;
PUSH DWORD PTR AStrValue;
CALL ACode;
end;
end;
動作バージョンをテストするには、以下を呼び出す必要があります。
procedure ...;
var
LObj: TMyObj;
LMethod: TMethod;
LStrVal: string;
LIntVal: Integer;
begin
LObj := TMyObj.Create;
try
LMethod.Data := Pointer( LObj );
LMethod.Code := LObj.MethodAddress('testex');
LStrVal := 'The year is:' + sLineBreak;
LIntVal := 2012;
CallObjMethWorking(LMethod, LStrVal, LIntVal);
finally
LObj.Free;
end; // tryf
end;
動作しないバージョンをテストするには、次のようにします。
procedure ...;
var
LObj: TMyObj;
LCode: Pointer;
LData: Pointer;
LStrVal: string;
LIntVal: Integer;
begin
LObj := TMyObj.Create;
try
LData := Pointer( LObj );
LCode := LObj.MethodAddress('testex');
LStrVal := 'The year is:' + sLineBreak;
LIntVal := 2012;
CallObjMethNOTWorking(LData, LCode, LStrVal, LIntVal);
finally
LObj.Free;
end; // tryf
end;
そして最後に質問:CallObjMethWorkingが機能しているのに、なぜCallObjMethNOTWorkingが機能していないのですか?コンパイラがTMethodをどのように扱うかには何か特別なことがあると思いますが...アセンブリの知識が限られているため、理解できません。
誰かが私にこれを説明してくれれば幸いです、ありがとう!