Советы по 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