Способ преобразования указателей на указатели на функции
Часто вам нужно указатель на функцию для функции обратного вызова. Но то, что ,
если вы хотите указать метод обратного вызова , как? Преобразованиеметода
Указатель на функцию указателя не является тривиальной задачей, оба типа
incomatible друг с другом. Хотя у вас есть возможность преобразования ,
как это " @ TClass.SomeMethod " , это больше , чем рубить
решением, поскольку оно ограничивает применение этого метода в какой-то
класса функций , где вы не можете получить доступ к переменным экземпляра .
Если вы этого не сделаете , вы получите замечательную GPF . Но есть
Лучшее решение : запустить время генерации кода! Просто выделите
исполнимые блок памяти , и 4-кратная машинных инструкций в
она : 2 Инструкции загружает два указателя метода указатель
(код и данные ) в регистрах, в одном вызывается метод через код
указатель , а последние просто возвращение Теперь вы можете использовать этот указатель
на выделенную память в виде простого указателя Funtion , но на самом деле вы
вызове метода для конкретного экземпляра класса.
Code: |
type TMyMethod = procedureofobject;
function MakeProcInstance(M: TMethod): Pointer; begin // allocate memory GetMem(Result, 15); asm // MOV ECX, MOV BYTE PTR [EAX], $B9 MOV ECX, M.Data MOV DWORD PTR [EAX+$1], ECX // POP EDX MOV BYTE PTR [EAX+$5], $5A // PUSH ECX MOV BYTE PTR [EAX+$6], $51 // PUSH EDX MOV BYTE PTR [EAX+$7], $52 // MOV ECX, MOV BYTE PTR [EAX+$8], $B9 MOV ECX, M.Code MOV DWORD PTR [EAX+$9], ECX // JMP ECX MOV BYTE PTR [EAX+$D], $FF MOV BYTE PTR [EAX+$E], $E1 end; end;
procedure FreeProcInstance(ProcInstance: Pointer); begin // free memory FreeMem(ProcInstance, 15); end;
{ After all, you should not forget to release the allocated memory. "TMyMethod" can be modified according your specific needs, e.g. add some parameters for a WindowProc. N.B.: Yes, I know, Delphi has those "MakeProcInstance" function in its forms unit. But this works a little bit different, has much more overhead, and most important, you have to use the forms unit, which increases the size of your exe drastically, if all other code doesn't use the VCL (e.g. in a fullscreen DirectX/OpenGl app).
// Wer noch Fragen hat / if you have questions: } |
Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.
ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!