Советы по Delphi. Версия 1.4.3 от 1.1.2001 - страница 16

стр.

>

>begin

> AForm := ActiveForm as TBaseForm;

> AForm.Method1;

>end

Указатель на функцию II

Delphi 1

Что лично я использую, чтобы вызвать какую-то функцию из DLL:

1. Объявите тип:

>type TYourDLLFunc = function(Parm1: TParm1; Parm2: TParm2): TParm3;

2. Объявите переменную этого типа:

>var YourDllFunc: TYourDLLFunc;

3. Получаем дескриптор DLL:

>DLLHandle := LoadLibrary('YourDLL.DLL');

Получаем адрес функции:

>@YourDLLFunc := GetProcAddress(DLLHandle, 'YourDLLFuncName');

Для использования функции теперь используйте переменную YourDLLFunc, например:

>Parm3 := YourDLLFunc(Parm1, Parm2);

Использование указателей на целое

Delphi 1

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

>Type Pinteger: ^Integer;

>Var MyPtr: Pinteger;

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

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

Например,

>NEW(MyPtr) = GetMem(MyPtr, Sizeof(MyPtr)).

Возможно, вы захотите подсчитать количество целочесленных переменных. В этом случае ознакомьтесь с возможностями TList. Пока лучше используйте линейный массив (или указатель на первый элемент, чтобы вычислить их количество, достаточно разделить количество занимаемой массивом памяти на количество элементов).

Для полноты, это должно быть:

>NEW(MyPtr) = GetMem(MyPtr, SizeOf(MyPtr^));

SizeOf(MyPtr) всегда будет равен 4 байта, как 16-битный указатель.

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

>Type

> pIntArr = ^IntArr;

> IntArr  = Array[1..1000] of Integer;

>Var

> MyPtr : pIntArr;

>Begin

> GetMem(MyPtr, 10); { 10 = SizeOf(Integer) * 5 !!}

> { MyPtr[2]:=1; }

> <<<< Заполняем массив >>>>

> MyPtr[2]^:=1;

> FreeMem(MyPtr,10);

>End;

Технология похожа на ту, которуя Delphi использует при работе с pchar. Синтаксис очень похож:

>type intarray = array[0..20000] of integer;


>procedure TForm1.Button1Click(Sender: TObject);

>var

> xptr:  ^IntArray;

>begin

> GetMem(xptr, 10);

> xptr^[idx] := 1;  { где idx от 0 до 4, поскольку мы имеем 10 байте = 5 целых }

> FreeMem(xptr, 10);

>end;

Обратите внимание на то, в вам в действительности нет необходимости распределять массив для 20,000 элементов, но проверка диапазона Delphi не будет работать, если диапазон равен 20,000. (Предостережение будущим пользователям!)

Память

Функция MemAvail для Delphi2?

Delphi 2

В Delphi 1, для того, чтобы получить самый большой возможный участок памяти, мы могли использовать функцию MemAvail, существует ли эквивалент этой функции в Delphi 2?

Нет. Но чтобы получить аппроксимированную сумму доступной памяти, можно воспользоваться функцией API GlobalMemoryStatus (через поле dwAvailVirtual возвращаемой структуры TMemoryStatus).

Steve Schafer

Как работать с блоками памяти размером более 64K?

Nomadic советует:

Так можно помещать в один блок памяти записи из TList (TCollection):

>imlementation

> { To use the value of AHIncr, use Ofs(AHIncr). }

>procedure AHIncr; far; external 'KERNEL' index 114;


>const

> NEXT_SELECTOR: string[13] = 'NEXT_SELECTOR';


>function WriteData: THandle;

>var

> DataPtr: PChar;

> i: Integer;

>begin

> Result := GlobalAlloc(GMEM_SHARE or GMEM_ZEROINIT, {pазмеp большого блока});

> if Result = 0 then Exit;

> DataPtr := GlobalLock(Result);

> {записываем кол-во эл-тов}

> Inc(DataPtr, {pазмеp счетчика эл-тов})

> for i := 0 to {некий}Count-1 do begin

>  if LongInt(PtrRec(DataPtr).Ofs) + {pазмеp подблока} >l= $FFFF then begin

>   Move(NEXT_SELECTOR, DataPtr^, SizeOf(NEXT_SELECTOR)); {некая константа}

>   { коppекция сегмента }

>   PtrRec(DataPtr).Seg := PtrRec(DataPtr).Seg + Ofs(AHIncr);

>   PtrRec(DataPtr).Ofs := $0;

>  end;

>  Inc(DataPtr, {pазмеp нового блока});

> end; { for i }

> GlobalUnlock(Result);

>end;


>procedure ReadData(DataHdl: THandle);

>var

> DataPtr : PObjectCfgRec;

> RecsCount: Integer;

> i: Integer;

>begin

> if DataHdl = 0 then Exit;

> DataPtr := GlobalLock(DataHdl);

> RecsCount := PInteger(DataPtr)^;

> Inc(PInteger(DataPtr));

> for