Добрый день.
Помогите доперевести код на ASM x64.
Код:
{$IFDEF WIN64}
function CallFunc(const AObj: TObject; AMethod: Pointer; var AResult: Variant): Variant;
asm
.NOFRAME
PUSH RSI
PUSH RDI
LEA RCX, [AObj]
PUSH RCX
MOV RDX, AResult
CALL AMethod
MOV Result, 1
POP RAX
POP RCX
POP RDX
end;
function CallFuncParam(const AObj: TObject; AMethod: Pointer; var AResult: Variant; const AParams: Pointer): Variant;
asm
.PARAMS 64
PUSH RSI
PUSH RDI
MOV RAX, RCX
MOV RCX, RDX
MOV RDX, AResult
CALL AMethod
MOV Result, 1
POP RAX
POP RCX
POP RDX
end;
{$ENDIF}
function TmyClass.CallMethod(AObject: TObject; const AMethod: string; AParams: PVariant): Variant;
var
method_def: TmbMethod;
method: pointer;
pvar: pointer;
param_count: integer;
el_size: integer;
rez: Variant;
begin
method_def := FindMethod(AMethod);
if method_def = nil then
raise Exception.CreateFmt('Method not found', [AMethod]);
el_size := 0;
pvar := AParams;
if AParams = nil then
param_count := 0
else
if VarIsArray(AParams^) then
with PVarData(AParams).VArray^ do begin
param_count := Bounds[0].ElementCount;
pvar := Data;
el_size := ElementSize;
end
else
param_count := 1;
if method_def.ParamCnt <> param_count then
raise Exception.CreateFmt('BadMethodParamCount', [AMethod, method_def.ParamCnt, param_count]);
method := method_def.Addr;
// заносим параметры в стек в обратном порядке (stdcall)
{$IFDEF WIN32}
pvar := PAnsiChar(pvar) + (param_count - 1) * el_size;
while param_count > 0 do begin
asm
push pvar
end;
Dec(PAnsiChar(pvar), el_size);
Dec(param_count);
end;
asm
mov eax, [AObject] // передаем self
push eax
end;
// Если метод возвращает результат (функция), заносим Result в стек
if method_def.Result then
asm
push Result
end;
asm
call method
end;
{$ELSE}
if param_count = 0 then
rez := CallFunc(AObject, method, Result)
else begin
rez := CallFuncParam(AObject, method, Result, AParams)
end;
{$ENDIF}
end;
из dll вызываю методы:
Код:
function RegEmployee(const AEmployee: Variant): Variant; stdcall;
function GetStreets(const ASettlementID, AStreetType: Variant): Variant; stdcall;
Для методов без параметров CallFunc отрабатывает, и все ок.
Для методов с параметрами CallFuncParam отрабатывает, но параметры не могу заполнить.
Помогите дописать CallFuncParam чтобы заполнялись параметры.
Спасибо.