На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
  
> Overload + jmp/call
    Есть несколько overload-функций. Нужно выполнить прыжок инструкцией jmp (ну или call) в одну из них. Как указать именно нужную из overload-функций, если все названия одинаковые?
      Имхо никак. Это магия компилятора.
        По названию никак. Можно только при отладке определить адреса различных вариантов overload-функций и вызвать нужную по ее адресу\смещению.

        PS: По идее в dcu эти функции должны "как-то" различаться, например по манглингу имен (указанию типов параметров в названии функции), или еще как-то. Но как конкретно - х.з. (Это в случае, если речь идет о "пользовательских" функциях, т.к. в модуле System все неявные overload варианты имеют собственные "магические" имена).
          Есть 2 варианта:

          А)
          ExpandedWrap disabled
            const
              MyIntToStr32: function (Value: Integer): string = SysUtils.IntToStr;
              MyIntToStr64: function (Value: Int64): string = SysUtils.IntToStr;
             
            asm
              ...
              call [MyIntToStr64]
            end;
          Но это костыль...

          Б)
          ExpandedWrap disabled
            {$APPTYPE CONSOLE}
             
            function X16(Z: Smallint): Integer;
            begin
              Result := Z*16;
            end;
             
            function X32(Z: Longint): Integer;
            begin
              Result := Z*32;
            end;
             
            function X(Z: Smallint): Integer; overload; inline;
            begin
              Result := X16(Z);
            end;
             
            function X(Z: Longint): Integer; overload; inline;
            begin
              Result := X32(Z);
            end;
             
            function Test: Integer;
            asm
              mov eax,1
              jmp X32
            end;
             
            var A: Smallint;
            begin
              A := 1;
              WriteLn(X(A));
              WriteLn(Test);
            end.
          Но:
          1. В Delphi7 будет лишняя обёртка при вызове X (т.к. D7 не поддерживает inline-функции).
          2. Функции X16/X32 нельзя спрятать (например, в implementation-секции unit'а).

          Добавлено
          Цитата leo @
          PS: По идее в dcu эти функции должны "как-то" различаться, например по манглингу имен (указанию типов параметров в названии функции), или еще как-то. Но как конкретно - х.з. (Это в случае, если речь идет о "пользовательских" функциях, т.к. в модуле System все неявные overload варианты имеют собственные "магические" имена).
          Вот непонятно, как заставить сделать этот манглинг... в DCU имена одинаковые (и даже в MAP, в отладочной инфе EXE, в OBJ, если объект генерить). Короче, шляпа какая-то...

          Добавлено
          p.s. В System.dcu они тоже не различаются. Посмотрел и в D7, и в Tokyo...
            ExpandedWrap disabled
              type
                TFigure = class
                  procedure Draw; virtual;
                end;
                TRectangle = class(TFigure)
                  procedure Draw; override;
                end;
                TEllipse = class(TFigure)
                  procedure Draw; override;
                end;
               
              procedure TForm1.Button1Click(Sender: TObject);
              var Rectangle:TRectangle;
              P:procedure () of object;
              begin
              Rectangle:=TRectangle.Create;
              P:=Rectangle.Draw;
              p();
              end;
               
              procedure TForm1.Button2Click(Sender: TObject);
              var Rectangle:TRectangle;
              P:procedure () of object;
              Metod:TMetod absolute P;
              begin
              Rectangle:=TRectangle.Create;
              P:=Rectangle.Draw;
              asm
              mov  eax, DWord PTR [Method+TMethod.Data]
              call Short PTR [Method+TMethod.Code]
              end;
              end;


            Вот ещё парочка методов из справки
            Цитата
            Two additional directives allow assembly code to access dynamic and virtual methods: VMTOFFSET and DMTINDEX.

            VMTOFFSET retrieves the offset in bytes of the virtual method pointer table entry of the virtual method argument from the beginning of the virtual method table (VMT). This directive needs a fully specified class name with a method name as a parameter (for example, TExample.VirtualMethod), or an interface name and an interface method name.

            DMTINDEX retrieves the dynamic method table index of the passed dynamic method. This directive also needs a fully specified class name with a method name as a parameter, for example, TExample.DynamicMethod. To invoke the dynamic method, call System.@CallDynaInst with the (E)SI register containing the value obtained from DMTINDEX.

            Note

            Methods with the message directive are implemented as dynamic methods and can also be called using the DMTINDEX technique. For example:

            TMyClass = class
            procedure x; message MYMESSAGE;
            end;

            The following example uses both DMTINDEX and VMTOFFSET to access dynamic and virtual methods:

            program Project2;

            type
            TExample = class
            procedure DynamicMethod; dynamic;
            procedure VirtualMethod; virtual;
            end;

            procedure TExample.DynamicMethod;
            begin

            end;

            procedure TExample.VirtualMethod;
            begin

            end;

            procedure CallDynamicMethod(e: TExample);
            asm
            // Save ESI register
            PUSH ESI

            // Instance pointer needs to be in EAX
            MOV EAX, e

            // DMT entry index needs to be in (E)SI
            MOV ESI, DMTINDEX TExample.DynamicMethod
            // Now call the method
            CALL System.@CallDynaInst

            // Restore ESI register
            POP ESI
            end;

            procedure CallVirtualMethod(e: TExample);
            asm
            // Instance pointer needs to be in EAX
            MOV EAX, e

            // Retrieve VMT table entry
            MOV EDX, [EAX]

            // Now call the method at offset VMTOFFSET
            CALL DWORD PTR [EDX + VMTOFFSET TExample.VirtualMethod]

            end;

            var
            e: TExample;

            begin
            e := TExample.Create;
            try
            CallDynamicMethod(e);
            CallVirtualMethod(e);
            finally
            e.Free;
            end;
            end.


            Помимо этого:
            https://stackoverflow.com/questions/4186458...red-in-a-string
            И да на DelphiMaster мне что-то ещё советовали насчёт RTTI - найти не могу.
              Цитата Pavia @
              Вот ещё парочка методов из справки
              Помимо этого
              Это всё относится к методам, а мне нужно для обычных функций. Это не overload, это override :)
                А какая цель?
                  Цель - превратить изврат, о котором я писал в соседней теме в более симпатичный код :)
                    Имхо, ты пытаешься скрестить ежа высокоуровневых удобняшек с ужом низкоуровневой овероптимизации.
                      Да, вот така селекция...
                      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                      0 пользователей:


                      Рейтинг@Mail.ru
                      [ Script execution time: 0,0314 ]   [ 17 queries used ]   [ Generated: 19.04.24, 23:45 GMT ]