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

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

Sharemem [D7, WinXP]


Fantasist ©   (2004-11-16 21:34:00) 

Всем известно зачем нужен Sharemem в общем и зачем он используется. Вопрос следующий: есть dll, которая довольно интенсивно использует string в качестве входящих параметров в экспортируемых процедурах. Sharemem НЕ используеться! Вообще. И самое обидное, что ничего не рушиться. Как я только не пытался его обрушить - не получаеться. Dll-вский менеджер памяти никгода не пытаеться освободить память из под строки переданной в параметре. Как можно добиться ситуации, чтобы все-таки это грохнулось? И вроде как получается, что в подавляющем большинстве случаев, можно обойтись и без Sharemem?


GuAV   (2004-11-17 12:16:00) [1]

jack128 ©   (17.11.04 4:00) [13]
Распиши, что у тя происходит, плиз.

AV и потом полное падение среды и проекта.

jack128 ©   (17.11.04 4:00) [13]
Мои рассуждения

Совпадают с моими.


Digitman   (2004-11-17 08:20:00) [2]


> Fantasist


> Sharemem НЕ используеться! Вообще. И самое обидное, что
> ничего не рушиться. Как я только не пытался его обрушить
> - не получаеться


ну не сокрушайся уж так уж .. сейчас вмиг поломаем всю эту петрушку

для начала убери галку Build With Run-Time Packages из опций обоих проектов (и хост-приложения и ДЛЛ), выполни их полную пересборку и попробуй что из этого получилось ..


> Dll-вский менеджер памяти никгода не пытаеться освободить
> память из под строки переданной в параметре


с чего ты взял ? он, менеджер, прямо вот так сам тебе об этом и сказал ?


jack128   (2004-11-17 04:00:00) [3]

GuAV ©   (17.11.04 2:43) [11]
У нас будет строка со счетчиком ссылок 2
Каким таким образом ?

Да, ты прав - счетчик ссылок будет - "1".

GuAV ©   (17.11.04 2:47) [12]
А вот если еще и объяснишь почему - цены те не будет ;-)
GuAV ©   (17.11.04 2:47) [12]
s := Caption;

не совсем удачный пример. Непонятно откуда берется строка - из TControl.FText или из GetWindowText.

Например так

в EXE
procedure Test(s: string); external 'project2.dll' name 'Test';

procedure TForm1.Button2Click(Sender: TObject);
begin
 Test(StringOfChar('a', 10));
end;

в ДЛЛ

var
 storedStr: string;

procedure Test(s: string);
begin
 StoredStr := s;
end;

exports
 Test;

Мои рассуждения:

на выходе из StringOfChar строрка имеет Счетчик Ссылок = 1.  Когда она вошла в Test СС = 2.  При присвоении StroredStr := s; CC = 3.  При выходе из процедуры СС = 2 Ну и наконец - очичаем строку результата StringOfChar - CC = 1.  И память из под строки НЕ ОСВОБОЖДАЕТСЯ. Практика и окно CPU полностью подверждает мои  рассуждения.  Сразу же исключения я не получил. А вот при выходе из приложения - получил. Даже не AV, а некое Project1.exe raised too many consecutive exceptions.  Может менаджер памяти в D7 и D5 по разному работают, вот и получаешь исключение тут же.  Распиши, что у тя происходит, плиз.


GuAV   (2004-11-17 02:47:00) [4]

jack128 ©   (17.11.04 2:35) [10]
Практика - критерий истины"(с)

exe:

procedure TakesString(s: string); external 'project2.dll'

procedure TForm1.FormCreate(Sender: TObject);
var s: string;
begin
 s := Caption;
 TakesString(s);
end;


dll:

library Project2;

uses
 SysUtils,
 Classes;

var
 StoredString: string;

procedure TakesString(s: string);
begin
 StoredString := s;
end;

exports
 TakesString;

begin
end.


AV при выходе как я и обещал.


GuAV   (2004-11-17 02:43:00) [5]

jack128 ©   (17.11.04 2:35) [9]
У нас будет строка со счетчиком ссылок 2

Каким таким образом ?


jack128   (2004-11-17 02:35:00) [6]

GuAV ©   (17.11.04 2:11) [8]
наверное будет AV при выходе...

Не-а. наврядли. У нас будет строка со счетчиком ссылок 2, хотя на самом деле должен быть 1.  То есть мемлик, а не обращение к невыделенной или освобожденной памяти.


jack128   (2004-11-17 02:35:00) [7]

А вообще - "Практика - критерий истины"(с)


GuAV   (2004-11-17 02:11:00) [8]

jack128 ©   (17.11.04 1:45) [6]
так что в этом случае, действительно, AV получить сложновато..

Придумал.

Если полученную строку сохранить в dll в глобальной переменой, а в ехе она локальная переменная - результат функции... то наверное будет AV при выходе...


GuAV   (2004-11-17 01:51:00) [9]

jack128 ©   (16.11.04 22:08) [2]
procedure SetLengthZero(var s: string); export;
begin
SetLength(s, 0);
end;


jack128 ©   (17.11.04 1:45) [6]
procedure SetLengthZero(s: PString); export;
begin
SetLength(s^, 0);
end;


ещё вариант:

funciton GetSomeString: string;


jack128   (2004-11-17 01:45:00) [10]

Fantasist   (16.11.04 22:21) [5]
Это, конечно, хорошо, но использование модификатора var во входящем параметре экспортной функции практика очень редкая.

Ну хорошо, давай так

procedure SetLengthZero(s: PString); export;
begin
 SetLength(s^, 0);
end;
Думаешь станет легче? ;-)
Использование string в экспортируемых функциях dll - вот это редкая и жестко наказуемая практика, а с вар параметрами проблем нет - посмотри, хотя бы функции из модуля Windows.

А вот если мы говорим строках переданных по значению (дальше идут измышления, НЕ проверенные практикой - ибо лень ;-)) тут дело вот в чем: при передаче по значению на входев функцию увеличивается счетчик ссылок строки на 1, а когда в dll хочет изменить эту строку, то её Memory Manager уменьшает счетчик ссылок строки и копрует её содержимое в новую строку, и производит изменения над копией. То есть он не уменьшает и не увеличивает длину строки, которая была создана MM экзешника, так что в этом случае, действительно, AV получить сложновато..

Сейчас глянул в CPU - мои измышления похожи на правду ;-)


Fantasist   (2004-11-16 22:21:00) [11]


> procedure SetLengthZero(var s: string); export;
> begin
>  SetLength(s, 0);
> end;


 Это, конечно, хорошо, но использование модификатора var во входящем параметре экспортной функции практика очень редкая.


panov   (2004-11-16 22:19:00) [12]

jack128 ©   (16.11.04 22:08) [2]

как я понял, исходника DLL у него нет...


Fantasist   (2004-11-16 22:19:00) [13]

Код, однако, не мой, по-этому выкладывать все не буду (да и много), но примерно так:

DLL:


procedure LoadMap (Path, FileName : string; sx, sy : word); stdcall;
begin
  if m = nil then m := MapObj.Create;
  m.LoadFromFile(Path, FileName);
  m.Image.Width := min (sx, m.Image.Width);
  m.Image.Height := min (sy, m.Image.Height);
end;

...

Exports
  LoadMap;


Проект:


var
 s,s1:string;
begin
  s:='null';
  s1:='map';
  s:=s+'.'+s1;

  LoadMap(path + 'textures', s, ScrollBar2.Left, ScrollBar2.Top);
end;


 Я сам хотел прокомментировать, что типа вот, у тебя ShareMem нету, напорешься на проблемы... Ну так как их продемонстрировать, что-то не нашел.


jack128   (2004-11-16 22:08:00) [14]

Fantasist   (16.11.04 21:34)
Dll-вский менеджер памяти никгода не пытаеться освободить память из под строки переданной в параметре


в длл
procedure SetLengthZero(var s: string); export;
begin
 SetLength(s, 0);
end;

в exe

var
 s:  string;
begin
 s := StringOgChar('a', 100);
 SetLengthZero(s);
end;
100/1 - будет АВ(сам не проверял -))


panov   (2004-11-16 21:36:00) [15]

примеры нужны, однако...


Наверх

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