Страница 1 из 1

Проблема с TStringList при закрытии программы.

СообщениеДобавлено: 08.01.2015 09:01:57
Sharfik
Исходники примера: https://yadi.sk/d/0ZCHPRzCdqXuy

В архиве программа+dll к ней. В исходниках показан кусок моей программы, как она дает dll работать с своими командами. Все работает до момента обработки FormCloseQuery.
Суть следующая. Создается класс который предоставляет инструменты работы для библиотеки, и условно есть документ который программа обрабатывает. Если пользователь закрывает программу, то возникает FormCloseQuery. Если документ был закрыт до этого момента, то все хорошо, если документ открыт, то он закрывается и тут библиотека выполняет работу свою. Проблема в том, что когда угодно, До FormCloseQuery, после FormCloseQuery(если отмена закрытия была) доступен список TStringList, но если в момент выполнения FormCloseQuery пытаться с ним работать через dll, то финишь. Если без библиотеки, то все обрабатывается.
Как костыли прилепить я знаю, но вот может кто то скажет почему так?

Re: Проблема с TStringList при закрытии программы.

СообщениеДобавлено: 08.01.2015 13:22:41
zub
>>В архиве программа+dll к ней.
//ванга моде
не вижу общего менеджера памяти - 100% "очистка" строк в листе не менеджером в котором они выделены
>>Как костыли прилепить я знаю, но вот может кто то скажет почему так?
данный подход сам по себе костыль, такчто ненадо стесняться прилеплять))

update:
Код: Выделить всё
TAssiApp(Sender).Command('REFRESHINFOWINDOW');

Имхо такой способ общения плагина и ексе годится только для построения настраиваемого в рантайме гуя и команд которые превносит в систему плагин, по хорошему общепринятые функции (команды) должны экспортироваться (просто export или передача какойнить структуры с адресами) ексешником и в длл пользоваться обычным способом

Re: Проблема с TStringList при закрытии программы.

СообщениеДобавлено: 08.01.2015 21:18:21
Sharfik
zub писал(а):не вижу общего менеджера памяти - 100% "очистка" строк в листе не менеджером в котором они выделены

Нахрена? При уничтожении объекта в его классе должно быть в любом случае обработана очистка памяти. Только TList не уничтожает свои ссылки.

Код: Выделить всё
Procedure TStringList.Clear;

begin
  if FCount = 0 then Exit;
  Changing;
  [b]InternalClear;[/b]
  Changed;
end;

destructor TStringList.Destroy;

begin
[b] InternalClear;[/b]
  Inherited destroy;
end;


zub писал(а):Имхо такой способ общения плагина и ексе годится только для построения настраиваемого в рантайме гуя и команд которые превносит в систему плагин, по хорошему общепринятые функции (команды) должны экспортироваться (просто export или передача какойнить структуры с адресами) ексешником и в длл пользоваться обычным способом

Расскажи это создателям lisp и autocad. А вообще так и есть, подгружаемые в рантайме меню, команды из dll и команды с наборами параметров.

Re: Проблема с TStringList при закрытии программы.

СообщениеДобавлено: 08.01.2015 22:30:20
zub
Нахрена? При уничтожении объекта в его классе должно быть в любом случае обработана очистка памяти. Только TList не уничтожает свои ссылки.

Теперь не ванга моде.
ошибка внутри fpc_ansistr_decr_ref
Как бы не выполнялась очистка, руками, по уничтожению владельца или еще как... говорит о том что куча сломана, т.е. скорее всего как я выше и говорил один менеджер пытается чистить за другим

Только TList не уничтожает свои ссылки.

незнаю какие ссылки ты имеешь ввиду, я имею ввиду уничтожение строк лежащих в списке, судя по всему какраз вот это:
Код: Выделить всё
[b]InternalClear;[/b]


Создателям автокада мне сказать нечего, т.к. они не используют fpc в текущем его состоянии))

зы.
Я в пример особо не вникал, как я понял ошибка должна быть при закрытии окна программы и не должно быть если сначала нажать на кнопку. В моем транковом фпц ошибка присутствует в обоих случаях((

Re: Проблема с TStringList при закрытии программы.

СообщениеДобавлено: 08.01.2015 23:08:41
Sharfik
Теперь не ванга моде.

Так понятней.

Ну да, если типа "закрытие проекта" с вызовом dll через кнопку, а не по крестику формы и уже потом закрытие, то все нормально должно быть.
А какой версии fpc и lazarus у тебя?

Re: Проблема с TStringList при закрытии программы.

СообщениеДобавлено: 08.01.2015 23:48:09
zub
А какой версии fpc и lazarus у тебя?

Вчерашние транковые и лазарь и фпц

Re: Проблема с TStringList при закрытии программы.

СообщениеДобавлено: 11.01.2015 02:49:52
Sharfik
В общем так, для закрытия темы.
Тот пример и правда не рабочий в ноль. Он будет таким как надо если использовать интерфейсы или абстрактный класс предок. Т.е. с глюком только при закрытии.
zub, спасибо за замечание про менеджер.

Сделал такое решение, чтобы развязать одну строку из dll на две:
Код: Выделить всё
function Command(ACommandStr: String; var OutResultIndex: Integer): boolean;
var
  i,count,CharByte:integer;
  IncomCommandStr: String;
begin
     Result:=True;
     IncomCommandStr:='';
     Count:=Length(ACommandStr);
     for i:=1 to Count do
     begin
        CharByte:=ord(ACommandStr[i]);
        IncomCommandStr:=IncomCommandStr+char(CharByte);
    end;
   FCmdLast.Add(IncomCommandStr);
   OutResultIndex:=1;
end;

Re: Проблема с TStringList при закрытии программы.

СообщениеДобавлено: 11.01.2015 17:22:56
zub
Код: Выделить всё
IncomCommandStr:=IncomCommandStr+char(CharByte);

Из за таких мест в программе производительность очень страдает. Длина известна, что мешает выделить выделить за один раз строку и скопировать?
Даже в таком виде будет в разы быстрее
Код: Выделить всё
begin
     Result:=True;
     Count:=Length(ACommandStr);
     setlength(IncomCommandStr,Count);
     for i:=1 to Count do
     begin
        IncomCommandStr[i]:=ACommandStr[i];
    end;
   FCmdLast.Add(IncomCommandStr);
   OutResultIndex:=1;
end;


Я все равно не догоняю упорство в неиспользовании cmem. И классы имхо нафиг не нужны, если уже разделять exe и dll - пока о них стоит забыть