Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.12.05;
Скачать: CL | DM;

Вниз

Sharemem   Найти похожие ветки 

 
Fantasist   (2004-11-16 21:34) [0]

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


 
panov ©   (2004-11-16 21:36) [1]

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


 
jack128 ©   (2004-11-16 22:08) [2]

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 22:19) [3]

jack128 ©   (16.11.04 22:08) [2]

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


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

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

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 нету, напорешься на проблемы... Ну так как их продемонстрировать, что-то не нашел.


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


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


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


 
jack128 ©   (2004-11-17 01:45) [6]

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 - мои измышления похожи на правду ;-)


 
GuAV ©   (2004-11-17 01:51) [7]

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;


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

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

Придумал.

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


 
jack128 ©   (2004-11-17 02:35) [9]

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

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


 
jack128 ©   (2004-11-17 02:35) [10]

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


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

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

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


 
GuAV ©   (2004-11-17 02:47) [12]

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 при выходе как я и обещал.


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

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 по разному работают, вот и получаешь исключение тут же.  Распиши, что у тя происходит, плиз.


 
Digitman ©   (2004-11-17 08:20) [14]


> Fantasist


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


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

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


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


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


 
GuAV ©   (2004-11-17 12:16) [15]

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

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

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

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



Страницы: 1 вся ветка

Текущий архив: 2004.12.05;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.047 c
14-1099820385
Piter
2004-11-07 12:39
2004.12.05
Редакторы ресурсов


1-1100678269
M_Untitled
2004-11-17 10:57
2004.12.05
CharCase в буквах кирилицы.


14-1100766738
Dmitriy O.
2004-11-18 11:32
2004.12.05
Удаленное администрирование своих программ.


3-1099916303
denis24
2004-11-08 15:18
2004.12.05
изменение записей в гриде


1-1100825047
dolphin
2004-11-19 03:44
2004.12.05
stringgrid