powered by simpleCommunicator - 2.0.27     © 2024 Programmizd 02
Map
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Обработка exception в DLL
62 сообщений из 62, показаны все 3 страниц
Обработка exception в DLL
    #39548350
Kirill Lagunov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Уважаемые форумчане, доброго дня.
Столкнулся с проблемой :
Проект : Delphi XE + FireBird.
Использую в программе динамическую библиотеку, которую сам же и разрабатываю.
Код вызова библиотеки :
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
var
  DLLRoutine: function(AppHandle:HWND; HostDb : TIBDatabase) : Boolean; stdcall;
  DLLHandle: THandle;
...
  DLLHandle := LoadLibrary(PChar(lib));
  try
    @DLLRoutine := GetProcAddress(DLLHandle, PChar(func));
    if Assigned(DLLRoutine) then
      DLLRoutine(Application.Handle, Base.ibCon)
    else
      MessageDlg('Динамическая функция ' + aRunStr + ' не найдена', mtInformation, [mbOK], 0);
  finally
    FreeLibrary(DLLHandle);
  end;


Код обработки при выгрузке DLL :
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
procedure MainDllProc(Reason: integer);
var
  i: integer;
begin
  // При загрузке DLL
  if (Reason = windows.DLL_PROCESS_ATTACH)
  then
    begin
      Base  := TBase.Create(Application);
      Res := TRes.Create(Application);
      dxInitializeGDIPlus;
    end;
  // При выгрузке DLL
  if (Reason = windows.DLL_PROCESS_DETACH)
  then
    begin
      ReleaseExceptionObject;
      dxFinalizeGDIPlus;
      with Application do
      begin
        for i := ComponentCount - 1 downto 0 do
        try
          if (Components[i] is TForm) then
            Components[i].Free;
        except
        end;
        for i := ComponentCount - 1 downto 0 do
        try
          if (Components[i] is TDataModule) then
          begin
            Components[i].Free;
          end;
        except
        end;
      end;
    end;
end;


Суть вопроса :
Если при вызове DLL в обработчика срабатывает exception, который посылает FireBird (обработка хранимых процедур и вызов внутри процедуры)
Код: plsql
1.
2.
3.
    begin
      exception xxx_xxx;
    end

, то при завершении работы с DLL исполняемая программа зависает.
Заметил одну особенность поведения программы при вызове исключения :
Код: pascal
1.
2.
Module Load: OLEACC.dll. No Debug Info. Base Address: $6CC30000. Process XXX.exe (7884)
Thread Start: Thread ID: 5796. Process XXX.exe (7884)


Создается отдельный поток, который потом при DLL_PROCESS_DETACH не убивается.
Что делать в данной ситуации?
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548351
Kirill Lagunov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Забыл добавить, что если не срабатывает exception, то DLL выгружается без проблем.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548354
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kirill Lagunov,

Эксепшены, старты/убийства потоков и еще много чего - плохой стиль, а иногда и невозможно делать в DLL_PROCESS_ATTACH/DLL_PROCESS_DETACH. Об этом написано в MSDN, не хочется искать опять.
Сделай доп. две экспортируемые из длл функции Initialize/Finalize, которые и вызывай при успешном LoadLibrary. В них всё делай.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548356
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kirill Lagunov,

Да, забыл добавить. Выпускать из dll эксепшены наружу - тоже не очень стиль :)
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548357
Kirill Lagunov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
YuRock,

Суть то в том, что эти эксепшены FB-шные я не создаю в DLL, они обрабатываются на стороне сервера, а потом посылаются в программу.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
        
try
  Base.itransStoredProc.Commit;
  Result := True;
except
   on E : EIBError do
   begin
     Result := False;
     Base.itransStoredProc.Rollback;
   end;
end;


И, по сути, поток я тоже не создаю в DLL.
На счет Initialize/Finalize вне DLL почитаю, но вопрос немного в другом =)
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548359
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kirill LagunovСуть то в том, что эти эксепшены FB-шные я не создаю в DLL
Kirill LagunovИ, по сути, поток я тоже не создаю в DLL
Ты создаешь. Модули, которые ты используешь (например, которые работают с клиентской библиотекой FB) - это такая же "твоя программа", как и лично твой код. Бинарник отличий не видит.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548363
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kirill Lagunov
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
try
  Base.itransStoredProc.Commit;
  Result := True;
except
   on E : EIBError do
   begin
     Result := False;
     Base.itransStoredProc.Rollback;
   end;
end;


Этот странный код только в каких-то единичных случаях может не привести к тому, что исключение не попадет "наружу".
Если, например, транзакция не активна, то сначала будет исключение на Commit, а затем и в обработке этого исключения - на Rollback, и это второе исключение ты уже не обрабатываешь.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548367
Kirill Lagunov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
YuRockKirill Lagunov
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
try
  Base.itransStoredProc.Commit;
  Result := True;
except
   on E : EIBError do
   begin
     Result := False;
     Base.itransStoredProc.Rollback;
   end;
end;


Этот странный код только в каких-то единичных случаях может не привести к тому, что исключение не попадет "наружу".
Если, например, транзакция не активна, то сначала будет исключение на Commit, а затем и в обработке этого исключения - на Rollback, и это второе исключение ты уже не обрабатываешь.

Проверка на активность транзакции выше по коду в процедуре.
Код: pascal
1.
2.
3.
    begin
      if not Base.itransStoredProc.InTransaction then
        Base.itransStoredProc.StartTransaction;



YuRockKirill LagunovСуть то в том, что эти эксепшены FB-шные я не создаю в DLL
Kirill LagunovИ, по сути, поток я тоже не создаю в DLL
Ты создаешь. Модули, которые ты используешь (например, которые работают с клиентской библиотекой FB) - это такая же "твоя программа", как и лично твой код. Бинарник отличий не видит.

Это я понимаю, имел в виду, что не создаю их вручную.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548386
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kirill LagunovПроверка на активность транзакции выше по коду в процедуре.
Мало ли какие там ошибки
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548387
Kirill Lagunov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
YuRockKirill LagunovПроверка на активность транзакции выше по коду в процедуре.
Мало ли какие там ошибки

Ошибка явная, обработка исключения при вызове хранимой процедуры, которая передает код и текст исключения.
Вопрос тогда такой, как можно поток с этим исключением отловить и завершить, либо как при выгрузке DLL закрыть все потоки, созданные при вызове DLL?
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548388
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kirill Lagunov,

в DLL не должно возникать никаких exception, следует начинку каждой экспортируемой функции обернуть в try .. except и возвращать код ошибки. А если интересен и текст ошибки, то тут несколько вариантов: 1) либо добавить еще одну функцию, например GetLastErrotText, 2) либо через параметры функции
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548395
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
HostDb : TIBDatabase



Вы обмениваетесь объектами Delphi через границе модулей. Нафига вам тогда DLL?

Делайте пакет, сплошные плюсы:
- Нет проблем с DllMain, у пакетов инициализация/финализация вынесена в изолированные функции
- Нет проблем с исключениями через границы модулей, у пакетов вызываемый и вызывающий написаны на одном языке
- Нет проблем с передачей памяти и не нужны костыли, пакеты всегда неявно используют разделяемый менеджер памяти
- Экономится место, общий код вынесен в RTL/VCL пакеты
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548406
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуйте в длл при выгрузке дернуть
Код: pascal
1.
IBSQLMonitor.DisableMonitoring;
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548414
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kirill LagunovОшибка явная, обработка исключения при вызове хранимой процедуры, которая передает код и текст исключения.
Ну так обработай её таким образом, чтобы при обработке не могло возникнуть еще одного исключения.
Kirill LagunovВопрос тогда такой, как можно поток с этим исключением отловить и завершить
Вручную и больше никак. TIBDatabase потоки не порождает, на сколько мне известно. Разве что TIBEvents.RegisterEvents

И делать это надо (потоки останавливать, все объекты освобождать и т.д.) в доп. функции Finalize, о которой я выше писал.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548430
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockTIBDatabase потоки не порождает, на сколько мне известноТы ошибаешься. Курить IBSQLMonitor.pas
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548477
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

Если мониторинг включен, то да. А по умолчанию он выключен (TraceFlags=[]), как и эвентов по умолчанию нет.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548484
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockА по умолчанию он выключенУгу. Вот только он имеет свойство включаться
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
unit IB;

type
  TTraceFlag = (tfQPrepare, tfQExecute, tfQFetch, tfError, tfStmt, tfConnect,
     tfTransact, tfBlob, tfService, tfMisc);

............
procedure IBDataBaseError(FGDSLibrary : IGDSLibrary);
begin
  ..........................
  if (MonitorHook <> nil) then
    MonitorHook.SendError(IntToStr(sqlcode) + ' ' + IntToStr(IBErrorCode) + ' ' + usr_msg);
  if sqlcode <> -551 then
    raise EIBInterBaseError.Create(sqlcode, IBErrorCode, usr_msg)
  else
    raise EIBInterBaseRoleError.Create(sqlcode, IBErrorCode, usr_msg)
end;
//=============
unit IBSQLMonitor
...............
function MonitorHook: IIBSQLMonitorHook;
begin
  if (_MonitorHook = nil) and (not bDone) then
  begin
    CS.BeginWrite;
    if (_MonitorHook = nil) and (not bDone) then
    begin
      _MonitorHook := TIBSQLMonitorHook.Create;
      _MonitorHook._AddRef;
    end;
    CS.EndWrite;
  end;
  result := _MonitorHook;
end;

constructor TIBSQLMonitorHook.Create;
begin
  inherited Create;
  FEventsCreated := false;
  FTraceFlags := [tfQPrepare..tfMisc];  // Кто там что говорил о флагах?
  FEnabled := true;
end;

procedure TIBSQLMonitorHook.SendError(Msg : String);
begin
  if FEnabled then
    if (tfError in FTraceFlags) then
      WriteSQLData(StrError + Msg, tfError);
end;

procedure TIBSQLMonitorHook.WriteSQLData(Text: String;
  DataType: TTraceFlag);
begin
{$IFDEF MSWINDOWS}
  if not FEventsCreated then
  try
    CreateEvents;
  except
    Enabled := false;
    Exit;
  end;
  CS.BeginWrite;
  Text := CRLF + StrApplication + DBApplication.Title + ']' + CRLF + Text; {do not localize}
  CS.EndWrite;
  if not Assigned(FWriterThread) then
    FWriterThread := TWriterThread.Create;  // Сюрприз!!!
  FWriterThread.WriteSQLData(Text, DataType);
{$ENDIF}
end;

...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548500
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

Да, красиво, конечно. Но до такого не должно доходить. Я сейчас специально потестил. В TWriterThread.Execute и TReaderThread.Execute в отладке попадаю, только если TIBDatabase.TraceFlags <> []. Делал connect, starttransaction, execsql, fetch, commit...

Дальше разбираться лень. Да и если б это было так, у меня б все dll-ки, создающие внутри TIBDatabase, за всю жизнь написанные, некорректно выгружались бы, с проблемами из-за не остановленных потоков. А этого нет и не было никогда. Только если TIBDatabase не освободить - бывают проблемы (тоже разбираться лень, почему, ведь освобождать всё равно надо).
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548511
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockв отладке попадаю, только если TIBDatabase.TraceFlags <> []. Делал connect, starttransaction, execsql, fetch, commit...Выполни ExecSQL, но чтобы оператор поднял ошибку. Что-то типа
Код: sql
1.
2.
3.
4.
5.
CREATE PROCEDURE sp_except
AS
BEGIN
  EXCEPTION my_except;
END

Код: pascal
1.
2.
IBSQL1.SQL.Text := 'EXECUTE PROCEDURE sp_except';
IBSQL1.ExecQuery;

Или сделай какую нибудь вставку, приводящую к двойным уникальным ключам
YuRockДа и если б это было так, у меня б все dll-ки, создающие внутри TIBDatabase, за всю жизнь написанные, некорректно выгружалисьЯ на такое наткнулся в своем COM-сервере. Если с сервера приходит ошибка (т.е. вызывается IBDataBaseError), то приложение не выгружалось. Несмотря на то, что исключение перехватывалось и обрабатывалось
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548692
Кар-Кар
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GunSmoker
Код: pascal
1.
HostDb : TIBDatabase



Вы обмениваетесь объектами Delphi через границе модулей. Нафига вам тогда DLL?

Делайте пакет, сплошные плюсы:
- Нет проблем с DllMain, у пакетов инициализация/финализация вынесена в изолированные функции
- Нет проблем с исключениями через границы модулей, у пакетов вызываемый и вызывающий написаны на одном языке
- Нет проблем с передачей памяти и не нужны костыли, пакеты всегда неявно используют разделяемый менеджер памяти
- Экономится место, общий код вынесен в RTL/VCL пакетыНадо не пакеты, надо один пакет. Один bpl, а то много файлов выходит: vcl.bpl, rtl.bpl, forms.bpl, winapi.bpl и т.д. И чтобы он был встроен в exe, желательно. Чтоб глаза не видели и не осозновать. Я бы загулял: маленькие .dll-ки к программе, а в них по сути целые формы. Одним чертом либы пишутся специально под приложение, да и 20MB экзешник перекомпилировать каждый раз если не распилить на dll. У меня нет SSD.

try

finally
FreeLibrary(DLLHandle);
end;
^Finally значит что либа будет выгружена вне зависимости от того был ли exception. Зачем её вообще загружать тогда? Не ради же вызова какой-нибудь функции каждый раз.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548761
Kirill Lagunov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
GunSmoker
Код: pascal
1.
HostDb : TIBDatabase



Вы обмениваетесь объектами Delphi через границе модулей. Нафига вам тогда DLL?

Делайте пакет, сплошные плюсы:
- Нет проблем с DllMain, у пакетов инициализация/финализация вынесена в изолированные функции
- Нет проблем с исключениями через границы модулей, у пакетов вызываемый и вызывающий написаны на одном языке
- Нет проблем с передачей памяти и не нужны костыли, пакеты всегда неявно используют разделяемый менеджер памяти
- Экономится место, общий код вынесен в RTL/VCL пакеты

Из описания пакетов При использовании пакетов необходимо вкладывать в дистрибутив приложения все пакеты, на которые ссылается разрабатываемый вами пакет.

Если это утверждение верное, то такой вариант мне не особо подходит.
Библиотека делается для того, чтоб при изменениях не нужно было пересобирать основной проект.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548764
Kirill Lagunov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кар-КарGunSmoker
Код: pascal
1.
HostDb : TIBDatabase



Вы обмениваетесь объектами Delphi через границе модулей. Нафига вам тогда DLL?

Делайте пакет, сплошные плюсы:
- Нет проблем с DllMain, у пакетов инициализация/финализация вынесена в изолированные функции
- Нет проблем с исключениями через границы модулей, у пакетов вызываемый и вызывающий написаны на одном языке
- Нет проблем с передачей памяти и не нужны костыли, пакеты всегда неявно используют разделяемый менеджер памяти
- Экономится место, общий код вынесен в RTL/VCL пакетыНадо не пакеты, надо один пакет. Один bpl, а то много файлов выходит: vcl.bpl, rtl.bpl, forms.bpl, winapi.bpl и т.д. И чтобы он был встроен в exe, желательно. Чтоб глаза не видели и не осозновать. Я бы загулял: маленькие .dll-ки к программе, а в них по сути целые формы. Одним чертом либы пишутся специально под приложение, да и 20MB экзешник перекомпилировать каждый раз если не распилить на dll. У меня нет SSD.

try

finally
FreeLibrary(DLLHandle);
end;
^Finally значит что либа будет выгружена вне зависимости от того был ли exception. Зачем её вообще загружать тогда? Не ради же вызова какой-нибудь функции каждый раз.

Кар-Кар^Finally значит что либа будет выгружена вне зависимости от того был ли exception.

Странное заявление, ведь если бы библиотека выгружалась вне зависимости от того, был ли exception или нет, я бы сюда не писал =)
И, естественно, не для вызова одной функции это делается.
Проект достаточно большой, так сказать,кол-во конечных пользователей с каждым днем растет, есть разные отделы, у которых специфичные потребности к программе, а каждый раз пересобирать основной проект нет желания, т.к он в себе, по сути, держит все основные классы, функции, для работы штатного сотрудника и так же все сделано для внедрения динамических библиотек (обновление/проверки хеша и т.д)
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39548855
Kirill Lagunov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_YuRockTIBDatabase потоки не порождает, на сколько мне известноТы ошибаешься. Курить IBSQLMonitor.pas

Проблема оказалась слишком смешной, действительно, есть бага в IBSQLMonitor.
Решилось все очень просто :

Код в DLL
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
uses ..., IBSQLMonitor;
...
function DbInit(DB: TIBDatabase): boolean;
var
  i : integer;
begin
  result := false;
  if not base.ibcon.connected then
    base.ibcon := db;
  try
    base.ibcon.connected := true;
    DisableMonitoring; // Строчка, которая решила все проблемы =)
...



Источник
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #39549114
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kirill Lagunov
Код: pascal
1.
function DbInit(DB: TIBDatabase): boolean;

Я сталкивался с тем, что несмотря на вызов DisableMonitoring по загрузки библиотеки, в некоторых случаях он все равно включался. Разбираться из-за чего было лень, поэтому у меня DisableMonitoring вызывается дважды - в начале работы и в конце
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Обработка exception в DLL
    #40135088
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тоже посчастливилось столкнуться к подобным глюком в IBSQLMonitor (D2007).
У меня проблема выглядела следующим образом: если при попытке выполнить TIBDataSet.Connection := True (из доп. потока) возникает ошибка (например, Firebird выключен), то это штука лезла зачем-то в основной поток, а основной поток в свою очередь тоже висел на вызове TIBDataSet.Connection := True. В результате - взаимоблокировка.
Долго не мог разобраться. Воспроизводится только на рабочем проекте.
DisableMonitoring решил проблему.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40135386
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kirill Lagunov
Что делать в данной ситуации?

Задать себе вопрос - а нахрена мне вообще эта DLL. Я примерно на 99.99% уверен, что убедительного ответа на этот вопрос не существует, просто (судя по тому, что я вижу в приведённых исходниках) Вы полны решимости избежать хороших практик и собрать все грабли, которые существуют на этом пути.

YuRock
Выпускать из dll эксепшены наружу - тоже не очень стиль :)

Смотря для кого. Для тех, для кого это проблема, писать dll - вообще не очень стиль.

Кроик Семён
в DLL не должно возникать никаких exception, следует начинку каждой экспортируемой функции обернуть в try .. except и возвращать код ошибки. А если интересен и текст ошибки, то тут несколько вариантов: 1) либо добавить еще одну функцию, например GetLastErrotText, 2) либо через параметры функции

Какой ужас. Если бы так было в самом деле, стоило бы застрелиться.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40135398
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarer
Если бы так было в самом деле, стоило бы застрелиться.
Какие альтернативы?
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40135401
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Очевидно, не каждый делает DLL, использующуюся исключительно одним приложением,
собранным исключительно той же версией компилятора. Правда, сочетание этих двух
факторов делает бессмысленным само использование DLL, но кто ж Вам запретит...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40135404
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer
Тоже посчастливилось столкнуться к подобным глюком в IBSQLMonitor (D2007).
А с ФИБами сравнивал ?
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40135409
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов Рустам,

ФИБы не используем.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40135444
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Очевидно, не каждый делает DLL, использующуюся исключительно одним приложением

Это бессмысленное и не нужное условие. Тем не менее, мне было бы любопытно провести опрос - у кого сколько DLL "использующихся разными приложениями" и сколько DLL "использующихся исключительно одним приложением". Что-то мне подсказывает, что список жалующихся на проблемы с DLL практически совпадёт со списком тех, у которых доминирует "одно приложение".

Dimitry Sibiryakov
Правда, сочетание этих двух факторов делает бессмысленным само использование DLL

А это уже глупость, которую Вы ввернули только для того, чтобы хоть чучелом, хоть тушкой вырулить к желаемому ответу.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40135451
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarerЭто бессмысленное и не нужное условие.

Это абсолютно необходимое условие. Мы ведь всё ещё говорим о выбрасывании
исключения в DLL и его поимке в приложении? То есть об обеспечении как минимум
трёх условий:
1) Одинаковая система исключений;
2) Одинаковая двоичная раскладка класса исключения;
3) Использование одного и того же менеджера памяти для выделения экземпляра
класса исключения и его освобождения.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40135455
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
То есть об обеспечении как минимум трёх условий:

И какое из этих трёх условий мешает использовать DLL в нескольких приложениях?
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40135519
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarer
Dimitry Sibiryakov
То есть об обеспечении как минимум трёх условий:

И какое из этих трёх условий мешает использовать DLL в нескольких приложениях?

Зачем в этих условиях DLL, если есть BPL?
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40135549
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarer
И какое из этих трёх условий мешает использовать DLL в нескольких приложениях?
Вот это
Dimitry Sibiryakov
2) Одинаковая двоичная раскладка класса исключения;
С переходом на новую версию Delphi никто не будет пересобирать все dll
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40135554
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GunSmoker
Зачем в этих условиях DLL, если есть BPL?

Зачем иголка с ниткой, если есть топор? Меня всегда удивлял этот вопрос. Единственное преимущество BPL - её можно инсталлировать в IDE. Когда это не нужно (то есть в 99% случаев), она не имеет преимуществ - одни недостатки. Так зачем в этих условиях BPL, когда есть DLL?

_Vasilisk_
С переходом на новую версию Delphi никто не будет пересобирать все dll

То есть ты выбираешь ежедневный геморрой ради того, чтобы избежать одной занимающей несколько минут операции, которая случается не каждый год?
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40135556
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ребята, его не переубедишь!
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40135560
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Достаточно одной dll (плугина), написанной не на делфи представителем сторонней конторы. Даже в общую сборку не входящей.
Чтобы закончить разговор как о bpl, так и о dll, собранных на одной версии делфи.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40135561
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
white_nigger
Ребята, его не переубедишь!

Без разумных аргументов - не переубедишь, это точно.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40135616
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarerТак зачем в этих условиях BPL, когда есть DLL?

Автоматически решается вопрос менеджера памяти и классового рантайма. Плюс
неявные служебные функции инициализации/финализации, которые не загонят процесс
в дедлок, как это сделано в стартовом посте. В общем, квинтэссенция RAD: забота о программисте, чтобы ему не пришлось голову напрягать и знания о граблях по крупице накапливать.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40135617
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Автоматически решается вопрос менеджера памяти
Зачастую это минус, а не плюс.
Даже здесь на форуме не единожды проскакивали задачи по производительности, в которых одно из решений было - разбить работающие потоки по разным dll, чтобы избежать блокировок менеджера памяти.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40135628
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock
Даже здесь на форуме не единожды проскакивали задачи по производительности, в которых одно из решений было - разбить работающие потоки по разным dll, чтобы избежать блокировок менеджера памяти.

Для этого проще процессами параллелиться, а не длл'ки плодить.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40135634
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey
YuRock
Даже здесь на форуме не единожды проскакивали задачи по производительности, в которых одно из решений было - разбить работающие потоки по разным dll, чтобы избежать блокировок менеджера памяти.

Для этого проще процессами параллелиться, а не длл'ки плодить.
Есть плюсы и минусы.
Общая память - один из плюсов dll в сравнении с процессами в данном случае.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40135639
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarer
То есть ты выбираешь ежедневный геморрой ради того, чтобы избежать одной занимающей несколько минут операции, которая случается не каждый год?
Никакого геморроя не наблюдаю. Что я делаю не так?
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40136173
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Автоматически решается вопрос менеджера памяти и классового рантайма.

В смысле, то же самое, что в случае dll делается простановкой одной галочки? Ну типа плюс, конечно, но по сравнению с минусами примерно то же, что оловянный солдатик по сравнению со Статуей Свободы.

_Vasilisk_
Никакого геморроя не наблюдаю. Что я делаю не так?

Скорее всего - привык к геморрою и не считаешь его таковым. Например - поступаешь, как здесь советуют, то есть не выпускаешь исключений из dll и корячишься с кодами возврата. В целом, мне будет проще ответить, если я увижу пару примеров того, что ты считаешь негеморройным кодом.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40136389
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
softwarer
Кроик Семён
в DLL не должно возникать никаких exception, следует начинку каждой экспортируемой функции обернуть в try .. except и возвращать код ошибки. А если интересен и текст ошибки, то тут несколько вариантов: 1) либо добавить еще одну функцию, например GetLastErrotText, 2) либо через параметры функции

Какой ужас. Если бы так было в самом деле, стоило бы застрелиться.

Когда кто-то называет ужасом то, что я считаю исключительно добродетельной практикой, требуются весомые доводы, чтобы не считать озвученное мнение глупой ересью. Так что ждемс.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40136490
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fr0sT-Brutal
Когда кто-то называет ужасом то, что я считаю исключительно добродетельной практикой, требуются весомые доводы, чтобы не считать озвученное мнение глупой ересью. Так что ждемс.

Запрет каких-либо возможностей, предоставляемых инструментом, редко является добродетельной практикой. Каждый раз, когда я вижу очередное "у нас в команде запрещено наследование", "у нас запрещено использование фреймов" итп. - это переводится как "наш главный гуру настолько криворук, что не умеет этим пользоваться, и настолько самонадеян, что по его мнению и другие не смогут".

Цель программ, то, для чего вообще их пишут - выполнение бизнес-функций. Например, программа вычисления корней квадратного уравнения должна вычислять корни этого самого уравнения. В идеальном случае она будет содержать только код этого вычисления - и этого хватит, чтобы всегда сработать именно так, как нужно.

К сожалению, у нас пока что не идеальный мир, и в этом не идеальном мире, помимо бизнес-кода, программа должна содержать некоторое количество кода технического. Объявление переменных, проверка диапазонов допустимых значений, обработка исключений.... Это делает программу лучше, но одновременно размазывает, замыливает и маскирует главное - бизнес-логику. Для того, чтобы программа была хорошей (в плане - читаемой, легко сопровождаемой, содержащей как можно меньше ошибок и т. д.) технический код должен быть сколь возможно минимизирован и сколь возможно отделён от бизнес-логики. Будет верным сказать, что из двух инструментов, порождающих эквивалентные программы, лучше тот, который требует меньше технического кода, из двух подходов лучше тот, который при эквивалентном результате требует меньше технического кода.

В частности, коды возврата - очень нездоровая в смысле объёма технического кода практика. Пока программисты их использовали - даже простейшие бизнес-функции кодировались огромными простынями, в которых было очень сложно разбираться. Использовались специальные приёмы кодирования для того, чтобы хоть как-то справляться с этой сложностью. Когда появились исключения - нормальные программисты с восторгом за них ухватились, потому что они дали возможность писать куда более сложную бизнес-логику гораздо короче, гораздо яснее, не в пример сопровождаемее. Благодаря механизму исключений трудоёмкость адекватной реализации бизнес-логики (включая тестирование, отладку и последующее сопровождение) снизилась минимум на порядок.

В обсуждаемой ситуации у нас есть выбор. Можно писать DLL ровно так же, как обычный Delphi-код без DLL. Коротко и ёмко. А можно непонятно зачем повесить на себя дикий геморрой, в котором "обязательно перехватывать исключения", "использовать коды возврата" и прочие ужас-ужас-ужас. И остаётся только один вопрос - зачем? В тех редких случаях, когда на этот вопрос есть действительно разумный ответ - ok, придётся мучиться как в прошлом веке. Но в 90% случаев это просто идиотизм архитектора, поскольку для этого нет ну совершенно никаких объективных причин.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40136510
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Правильные посылы, за уши притянутые к конкретной проблеме
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40136512
MaratIsk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

Очевидно, не каждый делает DLL, использующуюся исключительно одним приложением,
собранным исключительно той же версией компилятора. Правда, сочетание этих двух
факторов делает бессмысленным само использование DLL, но кто ж Вам запретит...


+100500
dll ради dll )))
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40136660
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
softwarer
...

А, ты насчет данного конкретного случая. Просто утверждение прозвучало на редкость категорично, вот я и подумал - вдруг есть уже супер-мега-практика передавать исключения кросс-язычно, а я и не в курсе
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40136672
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fr0sT-Brutal
А, ты насчет данного конкретного случая. Просто утверждение прозвучало на редкость категорично, вот я и подумал - вдруг есть уже супер-мега-практика передавать исключения кросс-язычно, а я и не в курсе

Я пока так и не понял, что "исключительно добродетельного" в отсутствии практики передачи исключений из А в Б. Если такое желание натыкается на нерешаемые технические проблемы... ну, очень печально, но эпитет "добродетельно" меня озадачил.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40136740
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
softwarer
Я пока так и не понял, что "исключительно добродетельного" в отсутствии практики передачи исключений из А в Б. Если такое желание натыкается на нерешаемые технические проблемы... ну, очень печально, но эпитет "добродетельно" меня озадачил.

А что, разве не добродетельно ловить все возможные исключения, чтобы софтина не падала с "недопустимой операцией"? Нормального-то способа передать исключение из dll нет. Или есть?
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40136744
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fr0sT-Brutal
А что, разве не добродетельно ловить все возможные исключения, чтобы софтина не падала с "недопустимой операцией"? Нормального-то способа передать исключение из dll нет. Или есть?

Я не понимаю, о каком сценарии ты говоришь. Ну вот давай предположим, что в программе делается

Код: pascal
1.
2.
3.
hLib := LoadLibrary('my.dll');
pProc := GetProcAddress(hLib, 'MyProcedure');
pProc^(1, 2, 3, 4, 5);


Ну или аналогичное на любом другом ЯП. Внимание, вопрос. Что такого должно произойти внутри MyProcedure, чтобы при отловленных в ней исключениях всё было хорошо, а при неотловленных - софтина упала?
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40136760
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
softwarer

Я не понимаю, о каком сценарии ты говоришь. Ну вот давай предположим, что в программе делается

Код: pascal
1.
2.
3.
hLib := LoadLibrary('my.dll');
pProc := GetProcAddress(hLib, 'MyProcedure');
pProc^(1, 2, 3, 4, 5);


Ну или аналогичное на любом другом ЯП. Внимание, вопрос. Что такого должно произойти внутри MyProcedure, чтобы при отловленных в ней исключениях всё было хорошо, а при неотловленных - софтина упала?

Да что угодно. Хоть открытие несуществующего или занятого файла. Тысячи причин, как ты сам же сказал - исключения это удобный инструмент реакции на ошибки в процессе, а не сигнал о фатальном крэше. Но даже при связке Delphi+Delphi без заморочек исключение через границы не передашь.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40136762
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fr0sT-Brutal
Да что угодно. Хоть открытие несуществующего или занятого файла.

Ну и? Я не понимаю, каким образом от "открытия несуществующего файла" дойдёт до "софтина упала". Можно конкретно?

Fr0sT-Brutal
Но даже при связке Delphi+Delphi без заморочек исключение через границы не передашь.

При связке Delphi+Delphi нет никакой границы и никаких заморочек. Кроме тех, которые люди зачем-то делают сами себе без причины на пустом месте.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40136777
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
softwarer
Fr0sT-Brutal
Да что угодно. Хоть открытие несуществующего или занятого файла.

Ну и? Я не понимаю, каким образом от "открытия несуществующего файла" дойдёт до "софтина упала". Можно конкретно?

Хм, сейчас sysutils добавляет обертку, которая выплевывает messagebox с текстом исключения. Падать не упадет, да. Тем не менее, получить его из DLL тоже мало радости, особенно если это невизуальный жеватель данных.

softwarer
Fr0sT-Brutal
Но даже при связке Delphi+Delphi без заморочек исключение через границы не передашь.

При связке Delphi+Delphi нет никакой границы и никаких заморочек. Кроме тех, которые люди зачем-то делают сами себе без причины на пустом месте.

Ну так расскажи, как обрабатывать исключения, кинутые в DLL, из программы-вызывателя
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40136781
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fr0sT-Brutal
Хм, сейчас sysutils добавляет обертку, которая выплевывает messagebox с текстом исключения. Падать не упадет, да.

Ты вот про эту обёртку? Так она существует со времён Delphi 1, и DLL не привносит сюда никакой специфики.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
procedure TApplication.Run;
begin
  ...
  repeat
    try
      HandleMessage;
    except
      HandleException(Self);
    end;
  until Terminated;
  ...
end;



Fr0sT-Brutal
Тем не менее, получить его из DLL тоже мало радости, особенно если это невизуальный жеватель данных.

Радость здесь вообще какая-то странная эмоция. Скажем так, её всяко больше по сравнению с "кодами возврата", GetLastError-ами и прочими костылями выпуска 1970-х.

Fr0sT-Brutal
Ну так расскажи, как обрабатывать исключения, кинутые в DLL, из программы-вызывателя

Да как хочешь. Вот представь себе, что у тебя есть процедура DoSomethingInteresting. Которая "невизуальный жеватель данных" или что угодно ещё. Ты вызываешь эту процедуру где-то в своей программе, обрабатываешь исключения из неё как считаешь правильным. Так вот, если эта процедура лежит в DLL - и, соответственно, исключение брошено из DLL - вообще ничего не меняется. Ни одной строчки кода. Всё как работало, так и работает.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40136852
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
softwarer
Ты вот про эту обёртку? Так она существует со времён Delphi 1, и DLL не привносит сюда никакой специфики.

Нет, я про SysUtils.ExceptHandler. В DLL я Forms не подключаю, слава богу, не требуется этого изврата.

softwarer
Да как хочешь. Вот представь себе, что у тебя есть процедура DoSomethingInteresting. Которая "невизуальный жеватель данных" или что угодно ещё. Ты вызываешь эту процедуру где-то в своей программе, обрабатываешь исключения из неё как считаешь правильным. Так вот, если эта процедура лежит в DLL - и, соответственно, исключение брошено из DLL - вообще ничего не меняется. Ни одной строчки кода. Всё как работало, так и работает.

Хм, а знаешь, и в самом деле так. Поразительно. Delphi и тут соломки подстелил. Любопытно, как это работает - через Winapi? И будет ли работать с разными версиями компилятора. Тем не менее, сомневаюсь, что это будет надежно работать кросс-язычно.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40136876
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это работает через виртуальные методы. Это будет работать, только если DLL и хост собраны в одной/совместимой версии компилятора. Например, ANSI DLL не будет работать в Unicode Host и наоборот. Также это не будет работать, если от исключения надо не просто показать сообщение от него, а сделать что-либо ещё - например, изменить (если только не подключен общий менеджер памяти). Также не будет работать фильтрация исключений (если только она не выполняется по тексту имени класса, либо и DLL и host собраны с пакетами, содержащими класс исключения).

Короче говоря, "если" тут действительно много, про них все нужно знать и уметь обходить.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40136877
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GunSmoker
Короче говоря, "если" тут действительно много, про них все нужно знать и уметь обходить.

Тут ровно одна галочка в настройках, которую надо поставить. После чего не требуется ничего обходить, да и знать кроме этой галочки тоже не обязательно.
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40136895
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
GunSmoker
Это работает через виртуальные методы

Можешь пояснить, о чем речь?
...
Рейтинг: 0 / 0
Обработка exception в DLL
    #40136928
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На уровне ОС программные исключения кидаются как запись (record). В записи указывается уникальный фиксированный код Delphi исключений и ссылка на объект Delphi.

"Принимающая" сторона может увидеть код Delphi в записи и понять, что это - Delphi исключение. Из записи же прочитать ссылку на объект. Если раскладка в памяти совпадает - сможет прочитать из него свойство-строку (сообщение).

При выходе из except блока исключение нужно удалить. Делается это вызовом деструктора. В Delphi деструкторы всех объектов - виртуальные. Это значит, что в VMT объекта есть ссылка на код деструктора. Следовательно, "принимающая" сторона вызовет код по ссылке, указанной в самом объекте. Это будет код в другом модуле, который и так знает, как нужно удалить переданный ему объект (в плане какие функции управления памятью вызывать).

Если бы деструктор не был виртуальным, то при попытке очистке памяти объекта были бы вызваны функции не того менеджера памяти.
...
Рейтинг: 0 / 0
62 сообщений из 62, показаны все 3 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Обработка exception в DLL
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали тему (0):
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]