Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Выделение памяти для массива в DLL. [D7, WinXP]


gdaujk ©   (2006-08-03 17:57:00) 

Доброго времени суток, уважаемые Мастера. Ситуация следующая: в библиотеке есть экспортируемая функция:

function Example(var a: array of Real): Boolean;
begin
 //
end;


Подскажите, как внутри этой функции выделить (освободить)  память для массива без использования ShareMem и функции SetLength ?


Ketmar   (2006-08-04 12:44:00) [1]

> [13] Desdechado ©   (04.08.06 12:28)

ну, это если универсальная DLL. а если своя личная, и никому больше не нужна -- то тут уже, имо, удобство важнее. %-)


Desdechado   (2006-08-04 12:28:00) [2]

Хорошим тоном считается выделить память в проге, подсунуть адрес в DLL, там с ней чего-то поделать и вернуть в прогу, в проге чего-то поделать и освободить память.
Обрати внимание, как работает большинство winAPI-функций - они просят буфер для чего-то ДО запуска.


Ketmar   (2006-08-04 11:28:00) [3]

> [11] Reindeer Moss Eater ©   (04.08.06 10:21)

возможно. но хак. да и не упомянуто об этом в [3]. %-)


Reindeer Moss Eater   (2006-08-04 10:21:00) [4]

getbug. служебные области кто заполнять будет?

А что, это невозможно?


Ketmar   (2006-08-03 21:29:00) [5]

зачем Example возвращает Boolean, и почему проигнорирован warning компилятора в этом месте?

а так -- теперь всё более-менее прилично на первый взгляд. %-)

зыж не надо использовать Real, оно obsolete. %-)


gdaujk   (2006-08-03 19:57:00) [6]

Извиняюсь, немного неправильно сформулировал задачу. В общем надо было внутри DLL инициализировать и заполнить область памяти, которую потом (в виде массива) могло бы использовать главное приложение.
Согласен и с Ketmar (насчёт ореха :-) и с DiamondShark. Привожу то, что получилось. Если есть варианты получше, выкладывайте.

library Project1;

uses
 Windows;

type
 TRealArr = array of Real;
 PRealArr = ^TRealArr;

function Example(var A: Pointer; aSize: Integer): Boolean;  stdcall;
var
 I: Integer;
begin
 A := VirtualAlloc(nil, aSize * SizeOf(Real), MEM_COMMIT, PAGE_READWRITE);
 for I := 0 to aSize - 1 do
   TRealArr(A)[I] := I;
end;

procedure dgaFillArray(var A: Pointer; aSize: Integer); stdcall;
var
 I: Integer;
begin
 GetMem(A, aSize * SizeOf(Real));
 for I := 0 to aSize - 1 do
   TRealArr(A)[I] := I;
end;

procedure dgaFreeArray(var A: Pointer); stdcall;
begin
 FreeMem(A);
end;

exports
 Example, dgaFillArray, dgaFreeArray;

begin
end.


В главном приложении:

type
 TRealArr = array of Real;
 PRealArr = ^TRealArr;

function Example(var A: Pointer; aSize: Integer): Boolean; stdcall;
procedure dgaFillArray(var A: Pointer; aSize: Integer); stdcall;
procedure dgaFreeArray(var A: Pointer); stdcall;

implementation

function Example; external 'Project1.dll' name 'Example';
procedure dgaFillArray; external 'Project1.dll' name 'dgaFillArray';
procedure dgaFreeArray; external 'Project1.dll' name 'dgaFreeArray';

procedure TForm1.FormActivate(Sender: TObject);
var
 P: Pointer;
 A: Pointer;
begin
 Example(P, 10);
 Label1.Caption := FloatToStr(TRealArr(P)[5]);
 VirtualFree(P, 0, MEM_RELEASE);
 dgaFillArray(A, 10);
 Label2.Caption := FloatToStr(TRealArr(A)[5]);
 //FreeMem(A);     // ошибка
 dgaFreeArray(A);  // правильное освобождение памяти
end;


begin...end   (2006-08-03 19:30:00) [7]

А о каком массиве идёт речь? Об a? Так ведь это же открытый массив.


Ketmar   (2006-08-03 19:25:00) [8]

> [6] DiamondShark ©   (03.08.06 18:49)

ну да. пардон, забыл это уточнить. %-)


DiamondShark   (2006-08-03 18:49:00) [9]

Ничего страшного без ШареМем не случится.
Если, конечно, память отдавать на освобождение туда же, где она и выделялась.


Ketmar   (2006-08-03 18:40:00) [10]

ну и -- без ShareMem с менеджером памяти случится злой маразм.


Ketmar   (2006-08-03 18:39:00) [11]

> [3] Reindeer Moss Eater ©   (03.08.06 18:37)

getbug. служебные области кто заполнять будет?


Reindeer Moss Eater   (2006-08-03 18:37:00) [12]

getmem


Ketmar   (2006-08-03 18:06:00) [13]

точно так же, как скомпилировать программу на дельфи, не имея установленной дельфи и вообще не имея компьютера в области досягаемости.


Ketmar   (2006-08-03 18:06:00) [14]

орешек.


Наверх

Титульная страница Поиск, карта сайта Написать письмо