Форум: "WinAPI";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.04.25;
Скачать: [xml.tar.bz2];




Вниз

Как создать динамический масив? 


BVS   (2002-02-06 17:15) [0]

Привет.

Как создать динамический масив используя только средства API.
И как добавлять в него новые элементы.

Спасибо.



Suntechnic   (2002-02-06 17:54) [1]

Динамический массив чего? И какие такие средства какого такого API?



BVS   (2002-02-06 21:38) [2]

LPINTERNET_CACHE_ENTRY_INFO lpCacheEntry[n]

n - заранее не известен.



Фэ   (2002-02-07 00:20) [3]

Всеобщее помешательство на API..
Сайт-то про Дельфи.



Tosov   (2002-02-07 00:50) [4]

BVS
А как создать переменную средствами API?
cbInt:Integer;



Digitman   (2002-02-07 10:49) [5]

LPINTERNET_CACHE_ENTRY_INFO - где и как декларирован этот прототип ?



Фэ   (2002-02-07 11:26) [6]

wininet.pas

function RetrieveUrlCacheEntryFileA(lpszUrlName: PAnsiChar;
var lpCacheEntryInfo: TInternetCacheEntryInfo;
var lpdwCacheEntryInfoBufferSize: DWORD;
dwReserved: DWORD): BOOL; stdcall;



VuDZ   (2002-02-07 11:29) [7]

LPINTERNET_CACHE_ENTRY_INFO - указатель на _INTERNET_CACHE_ENTRY_INFO - SDK посматривать надо бы хоть изредка....

Фэ
Всеобщее помешательство на API..
Сайт-то про Дельфи.

ну и много ты на делфи сделаешь без API?

BVS
LPINTERNET_CACHE_ENTRY_INFO lpCacheEntry[n]
на С это можно сделать разными путями:
1.
LPINTERNET_CACHE_ENTRY_INFO lpCacheEntry = new _INTERNET_CACHE_ENTRY_INFO[n];

2. BYTE * lpCEntry = new BYTE[sizeof(_INTERNET_CACHE_ENTRY_INFO) * n];

смысл ясен?
выдели просто структуру в байтах, чей размер равен размеру _INTERNET_CACHE_ENTRY_INFO * n раз



Фэ   (2002-02-07 12:09) [8]

Вот и пишите на Си.
Либо приводите эквивалентный код.

В дельфи есть динамические массивы.
ii: array of TInternetCacheEntryInfo;
..
SetLenght(ii,20);



Digitman   (2002-02-07 12:16) [9]

>VuDZ
То-то я смотрю - ты все SDK вдоль и поперек изучил, коль "динамические массивы" в Win32API выискал).. а в механизме распределения структурированной памяти "плаваешь")

У тебя есть размер структуры, есть переменная-указатель на блок памяти, куда WinAPI-вызов должен скопировать блок из N таких структур, так в чем же дело ? Выделяй память размером в N * SizeOf(структура) любым доступным способом и передавай его в кач-ве параметра !



VuDZ   (2002-02-07 12:25) [10]

1.
>То-то я смотрю - ты все SDK вдоль и поперек изучил,
>коль "динамические массивы" в Win32API выискал
где ты это у меня увидел?
где у меня win32API

2.
>.. а в механизме распределения структурированной
>памяти "плаваешь")
а это то тут причём?

3.
>У тебя есть размер структуры, есть переменная-указатель на
>блок памяти, куда WinAPI-вызов должен скопировать блок из N
>таких структур, так в чем же дело ? Выделяй память размером в
>N * SizeOf(структура) любым доступным способом и передавай его
>в кач-ве параметра !
а я о чём писал?

я что-то тебя не понял...



Pete   (2002-02-07 12:55) [11]

unit Unit1;


interface


uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls;


type
ElementType = Integer;


const
MaxArraySize = (65520 div SizeOf(ElementType));
{ в 16-битной среде }


type
{ Создаем тип массива. Убедитесь в том, что вы установили
максимальный диапазон, который вам, вероятно, может понадобиться. }
TDynamicArray = array[1..MaxArraySize] of ElementType;
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;


var
Form1: TForm1;
{ Создаем переменную типа указатель на ваш тип массива. }
P: ^TDynamicArray;


const
{ Это типизированные константы. В действительности они
являются статическими переменными, инициализирующимися
во время выполнения указанными в исходном коде значениями.
Это означает, что вы можете использовать типизированные
константы точно также, как и любые другие переменные.
Удобство заключается в автоматически инициализируемой величине. }
DynamicArraySizeNeeded: Integer = 10;


implementation


{$R *.DFM}


procedure TForm1.FormCreate(Sender: TObject);
begin
{ Распределяем память для нашего массива. Будь внимательны
и распределяйте размер, в точности необходимый для размещения нового массива.
Если вы попытаетесь записать элемент, выходящий за допустимый диапазон,
компилятор не ругнется, но объект исключения вам обеспечен. }
DynamicArraySizeNeeded := 500;
P := AllocMem(DynamicArraySizeNeeded * SizeOf(Integer));
{ Как присвоить значение пятому элементу массива. }
P^[5] := 68;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
{ Вывод данных. }
Button1.Caption := IntToStr(P^[5]);
end;


procedure TForm1.FormDestroy(Sender: TObject);
begin
{ Освобождаем распределенную для массива память. }
FreeMem(P, DynamicArraySizeNeeded * SizeOf(Integer));
end;


end.


Не мой пример, но я пользуюсь им для создания динамических массивов. Очень просто.

Или подобно пользуй GetMem и FreeMem



Digitman   (2002-02-07 18:27) [12]

>VuDZ
п1. Распределением вирт.памяти "заведует" Win32. Ты же хочешь создать некий массив, так ? Значит - запросить память под него, так ? Значит, на самом низком уровне, все же - Win32API, так ?

п2. А притом, что самостоятельно ты не смог сообразить, что интересующий тебя вызов возвращает N последовательно расположенных структур определенного типа. Вопрос - куда возвращать ? Распределением памяти под возвращаемый структурированный массив в этом случае должно заведовать приложение, т.е. запросить у ОС ровно такой блок памяти, которого достаточно для размещения N последовательных структур заданного размера (читай - блок памяти размером в произведение N на размер_структуры байт) и передать типизированный указатель на этот блок в кач-ве параметра для вызова API-ф-ции.

п3. Уже <Pete> все пояснил тебе



VuDZ   (2002-02-07 19:36) [13]

ладно, я уже пришёл в кондицию и скажу пару слов:
п1. Распределением вирт.памяти "заведует" Win32. Ты же хочешь создать некий массив, так ? Значит - запросить память под него, так ? Значит, на самом низком уровне, все же - Win32API, так ?
тот пример (точнее 2) который приводил я - обращается к библиотечным функциям STL для выделения памяти независимо от типа переменной, но используется работа с heap"ом - если есть желание - VC98\CRT\SRC\MALLOC.C - тут всё хорошо написано...
Но я так и не понял, о чём ты хотел сказать
Интересно, а как ты выделишь память без win32api под виндой? да же если у тебя есть свой менеджер памяти, он то должен откуда то взять указатель на некоторый регион памяти
А динамический массив или нет - неважно, просто в первом случае надо перераспределять память GlobalReAlloc() - для примера, а во втором - только освободить по окончанию работы с ней

п2. А притом, что самостоятельно ты не смог сообразить, что интересующий тебя вызов возвращает N последовательно расположенных структур определенного типа. Вопрос - куда возвращать ? Распределением памяти под возвращаемый структурированный массив в этом случае должно заведовать приложение, т.е. запросить у ОС ровно такой блок памяти, которого достаточно для размещения N последовательных структур заданного размера (читай - блок памяти размером в произведение N на размер_структуры байт) и передать типизированный указатель на этот блок в кач-ве параметра для вызова API-ф-ции.
во-первых, не надо наежать, во-вторых, это уже начинает напоминать анекдот про натовских лётчиков - то ли зрение -20, то ли карты старые:
выдели просто структуру в байтах, чей размер равен размеру _INTERNET_CACHE_ENTRY_INFO * n раз
по моему я сказал то же самое - или у нас кодировка разная?

п3. Уже <Pete> все пояснил тебе
и?
я, знаешь ли, плохо понемаю по вашему, особенно без цветового выделения...

PS Digitman, я так и не понял, что ты хотел мне сказать своими постами? Или это желание сказать всем, что типа - вот этот парень неправ, независимо от того, что он написал. а вот моё мнение - верное и всё.
Есть ещё что сказать?



Suntechnic   (2002-02-08 00:25) [14]

Флейм ну прямо из пальца высосали :)...

>VuDZ ©
Я бы на твоём месте попридержал бы жеребцов. Я сам бы мог прочитать здесь лекцию по поводу работы с динамической памятью в С++, но форум всё-таки по Delphi, так что это здесь абсолютно неуместно. Ну кому спрашивается интересно здесь читать вот эту строчку?
LPINTERNET_CACHE_ENTRY_INFO lpCacheEntry = new _INTERNET_CACHE_ENTRY_INFO[n];

Пользы от этого ноль....

>Digitman ©
Я честно говоря тоже не совсем понял что ты пытался втолковать VuDZ ©... С точки зрения С++ у него в общем-то правильно написано(я говорю "вообщем-то" потому как совсем не понятно, что надо автору. Если быть достаточно точным, то запись BVS (06.02.02 21:38) LPINTERNET_CACHE_ENTRY_INFO lpCacheEntry[n] означает, что автору необходим динамический массив указателей на _INTERNET_CACHE_ENTRY_INFO, а не сам динамический массив этих структур), но с другой стороны какое это отношение имеет к Делфи?

>All
А вообще правильнее всех ответил на вопрос Tosov © (07.02.02 00:50) :)



Digitman   (2002-02-08 08:40) [15]

>VuDZ
Приношу извинения. Все мои реплики были адресованы не тебе, а автору (НИКи мной перепутаны). Меня сбила с толку твоя фраза о некоем SDK, который "нужно посматривать надо бы хоть изредка".

Прекратим беспредметный флейм ?



VuDZ   (2002-02-08 10:09) [16]

да



AndrewBee   (2002-02-09 08:37) [17]

Замучили вы динамическими массивами :о(((
Класс TList специально создан такие проблемы решать !



Evgeny   (2002-02-09 08:48) [18]

>AndrewBee
Вы когда-нибудь смотрите тему форума? Для тех кто не умеет читать. Этот форум по WinAPI!



AndrewBee   (2002-02-09 08:53) [19]

Да знаю :о)
Просто нафига сложности то лепить ?
Когда в VCL есть специально созданый (очень продуманный) класс для решения проблем динамических массивов.



Milz   (2002-02-11 10:23) [20]

Согласен с AndrewBee, но если очень хочется, то можно ...

Создание массива описал Pete, изменение размерности:

pTemp: ^TDynamicArray;

getMem (pTemp, sizeof(ElementType ) * newnumelements);
memcopy (pTemp, pMyArray, sizeof(ElementType )*n);
{n - количество элементов в pMyArray}
freeMem (pMyArray, sizeof(ElementType )*n);
pMyArray := pTemp;


>BVS
Если нужно подробнее пиши.



Иван Шихалев   (2002-02-11 20:38) [21]

В самом деле, нафига сложности лепить и 400 килобайт VCL линковать, если в язык еще с D4 введены динамические массивы и процедура SetLength?



Фэ   (2002-02-12 02:34) [22]

Тоже, не пойму - чего народ суетиться ?

Dir: array of TSearchRec;
..
SetLength(Dir,20);
..
SetLength(Dir, Length(Dir)+5);
..
Dir[7].Name; // доступ к телу

P.S. И главное - все ведь знают. Нет же, до рукопашной дошли.
Хотя, если вопрос принципа..



Эдуард   (2002-02-20 07:32) [23]

Вообще-то такая шняга как Dir: arra or Чего-нибудь позволяет поместить только 128 элементов (где-то прочитал я), на своем опыте пробовал, получилось только 126 =))



MBo   (2002-02-20 07:43) [24]

>только 128 элементов (где-то прочитал
значит, не те книжки читал и не так пробовал



SergeyDon   (2002-02-20 09:30) [25]

Согласен с МВо
делаю также как Фэ в масиви от 50 до 10000 элиментов все прикрасно работает. Причем элименты:
Record
a:integer;
b:string[5];
end {record}
Все лётает нечего делать!




Форум: "WinAPI";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.04.25;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.79 MB
Время: 0.023 c
1-80913           Reef                  2002-04-15 12:43  2002.04.25  
PChar and string


3-80799           Марина                2002-04-05 09:11  2002.04.25  
Table is busy.User:???


3-80823           Alexandr_             2002-04-05 15:00  2002.04.25  
ODAC. Проблема с чтением из BLOB


1-80967           DenKop                2002-04-11 13:35  2002.04.25  
Сообщение другой программе.


3-80771           Леонид                2002-04-04 10:08  2002.04.25  
Кнопка поля просмотра в TDBGrid