Способ преобразования указателей на указатели на функции  Часто вам нужно указатель на функцию для функции обратного вызова. Но то, что ,
 
если вы хотите указать метод обратного вызова , как? Преобразованиеметода
 
Указатель на функцию указателя не является тривиальной задачей, оба типа
 
incomatible друг с другом. Хотя у вас есть возможность  преобразования ,

StrAlloc непосредственно использует GetMem, поэтому обе функции живут за счет Кучи. StrAlloc имеет преимущество: он распределяет на два байта больше, чем вы просите и там хранит размер размещенного блока. Поэтому StrDispose знает сколько памяти освободить и вы можете этого не помнить (в отличие от GetMem/FreeMem). Не смешивайте при работе эти две функциональные пары, иначе вы будете потрясены количеством возникающих ошибок!

Я создал простой модуль и разработал несколько простых методов, помогающих избежать использования неактуальных (в оригинале было "stale" - черствый, несвежий) указателей. Я настоятельно рекомендую добавить во все модули, содержащие указатели или объектные переменные секцию инициализации ('initialization') и установить все указатели (объектные переменные это те же реальные указатели) в nil. Что это даст:

Сначала короткое объяснение арифметике указателя. Когда вы имеете дело с динамическими страницами памяти, то все, что вы имеете - это указатели на начала блоков памяти. Вы хотите просмотреть всю строку памяти, чтобы понять какие функции необходимы для работы с данными, хранящимися в памяти? Это возможно путем изменения места в памяти, на которое указывает указатель. Это называется арифметикой указателя.

 

Тут мы рассмотрим несоклько примером освобождения памяти.

Я ищу функцию, которая была бы эквивалентом сишной функции memcmp.

Я создал следующие две функции, существенно повышающие произвотельность в приложениях, активно работающих с данными. Вам нужно всего-лишь обеспечить контроль типов и границ допустимого диапазона, все остальное они сделают с любым типом данных лучше нас :-) .

 

 

Code:

function Keys_are_Equal(var OldRec, NewRec;

KeyLn : word): boolean; assembler;

asm

PUSH    DS

MOV     AL,01

CLD

LES     DI,NewRec

LDS     SI,OldRec

MOV     CX,KeyLn

CLI

REPE    CMPSB

STI

JZ      @1

XOR     AL,AL

@1:

POP     DS

end;

 

Code:

function First_Key_is_Less(var NewRec, OldRec;

Keyln : word): boolean; assembler;

asm

PUSH    DS

MOV     AL,01

CLD

LES     DI,NewRec

LDS     SI,OldRec

MOV     CX,KeyLn

CLI

REPE    CMPSB

STI

JZ      @5

JGE     @6

@5: XOR     AL,AL

@6: POP     DS

end;

Если вы хотите удалить переменную, что никакая другая программа не может прочитать из памяти больше, просто используйте эту функцию:

 

Code:

ZeroMemory(Addr(yourVar), SizeOf(yourVar));

ZeroMemory(Addr(yourStr), Length(yourStr));

// ZeroMemory(Address of the variable, Size of the variable);

 

Очень полезно, если вы задали пароль, и вы хотите, что никто другой не может его получить.

 

Code:

uses WinCRT;

 

procedure TForm1.Button1Click(Sender: TObject);

var

MyArray: array[0..30] of char;

b: ^char;

i: integer;

begin

StrCopy(MyArray, 'Delphi World - это круто!!!');

b := @MyArray;

for i := StrLen(MyArray) downto0do

begin

   write(b^);

   inc(b, sizeof(char));

end;

end;

Code:

{ **** UBPFD *********** by delphibase.endimus .com ****

>> Получение размера памяти выделенный под Pointer

 

Функция возврящает количество байт выделенных под Pointer.

Размер округляется в большую сторону до DWORD (4 байт).

 

Зависимости: Windows

Автор:       Мироводин Дмитрий, mirovodin mail.ru

Copyright:   Мироводин Дмитрий

Дата:        16 октября 2013 г.

***************************************************** }

 

function GetPointerSize(const P: Pointer): Integer;

begin

if P = nilthen

   Result := -1

else

   Result := Integer(Pointer((Integer(p) - 4))^) and$7FFFFFFC - 4;

end;

Пример использования:

 

var

P: pointer;

PSize: integer;

begin

GetMem(P, 1024); // Размер кратен 4

PSize := GetPointerSize(P);

ShowMessage(inttostr(PSize)); // Результат 1024 байта

FreeMem(P);

end;

 

...

 

var

P: pointer;

PSize: integer;

begin

// Размер НЕ КРАТЕН 4

GetMem(P, 6);

PSize := GetPointerSize(P);

// Результат 8 байта т.к. идет округление

ShowMessage(inttostr(PSize));

FreeMem(P);

end;

Сначала вы должны создать тип:

Code:

Type Pinteger : ^Integer;

 

Var MyPtr : Pinteger;

 Мне кажется, что в начале вы использовали плохой пример, имеет смысл использовать 32-битный указатель для 16-битной величины или распределять 10 байт для переменной. 

 Pascal позволяет вам использовать методы NEW и DISPOSE, которые автоматически распределяют и освобождают правильные размеры блока. 

 Например:

 

...мне также понадобилось в подпрограмме получить ссылку на дочернее MDI-окно без сообщения подпрограмме с каким конкретно классом MDI необходимо работать. Что я сделал: я передавал в виде параметров тип дочернего MDI-окна и ссылку как нетипизированную переменную и затем обрабатывал это в подпрограмме.

 

Вот пример. Эта подпрограмма работает с дочерним окном, которое может иметь только один экземпляр. Если оно не открыто, подпрограмма создаст его, если оно открыто, оно переместит его на передний план.