Форум: "Основная";
Текущий архив: 2004.12.05;
Скачать: [xml.tar.bz2];
Вниз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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.033 c