|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Вызов метода из dll ASM x64
Добрый день.
Помогите доперевести код на 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 чтобы заполнялись параметры. Спасибо. |