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

Вниз

Задачка   Найти похожие ветки 

 
Loginov Dmitry ©   (2008-07-16 17:56) [0]

Весь моск сломал, пока разобрался в чем ошибка.

Вот (псевдо)код из EXE:


procedure MyProc;
var
 H: Cardinal;
 Proc: procedure;  
begin
 H := LoadLibrary("mydll.dll");
 if H <> 0 then
 begin
   Proc := GetProcAddress(H, "Proc");
if Assigned(Proc) then
try
  Proc();
except
  on E: Exception do
  begin
    ShowMessage(E.Message); // показываем пользователю ошибку
    FreeLibrary(H); // выгружаем библиотеку (от нее никакой пользы уже нет)  
  end;
end;
 end;
end;


Код процедуры в DLL


type
 EMyException = class(Exception);
 
procedure Proc;
begin
 raise EMyException.Create("Ошибка при работе функции Proc");
end;


Вопрос: почему при вызове функции MyProc выдается ошибка:
Access violation at address 20006F8C in module "rtl100.bpl". Read of address 00000000 (EAccessViolation)

Ответ оказался слишком простым, поэтому сообщу позже (желающие могут сами разобраться, все необходимое я привел). Интересно, кому нибудь приходилось разбираться с такими приколами? ;)


 
Loginov Dmitry ©   (2008-07-16 17:59) [1]

Блин, Notepad++ съел все форматирование :(


procedure MyProc;
 var
   H: Cardinal;
   Proc: procedure;
begin
   H := LoadLibrary("mydll.dll");
   if H <> 0 then
   begin
     Proc := GetProcAddress(H, "Proc");
     if Assigned(Proc) then
     try
       Proc();
     except
       on E: Exception do
       begin
         ShowMessage(E.Message); // показываем пользователю ошибку
         FreeLibrary(H); // выгружаем библиотеку (от нее никакой пользы уже нет)
       end;
     end;
   end;
end;


 
wl ©   (2008-07-16 18:10) [2]

что-то типа для передачи строк из dll в exe нужно подключить некий модуль?


 
Поросенок Винни-Пух ©   (2008-07-16 18:13) [3]

потому что возбуждено в длл, а обращение к строке идет в хост аппликейшен (а шаремема нет)

Exception = class(TObject)
.....
property Message: string read FMessage write FMessage;


 
Ega23 ©   (2008-07-16 18:21) [4]

Я бы ErrorCode из Dll возвращал, а не исключение генерил.
Но это так, к слову...


 
Mystic ©   (2008-07-16 18:27) [5]

Потому что в DLL своей класс Exception, а в твоем приложении свой.


 
Dimka Maslov ©   (2008-07-16 19:03) [6]

Можно ещё попробовать сгенерировать исключение в библиотеке, написанной на С.


 
Loginov Dmitry ©   (2008-07-16 19:18) [7]

> что-то типа для передачи строк из dll в exe нужно подключить
> некий модуль?



> Потому что в DLL своей класс Exception, а в твоем приложении
> свой.


И EXE и DLL скомпилированы с runtime-пакетами :)


 
Loginov Dmitry ©   (2008-07-16 19:19) [8]

ShowMessage(E.Message);
отрабатывает верно, показывает что и должно. Ошибка возникает после.


 
@!!ex ©   (2008-07-16 19:22) [9]

> скомпилированы с runtime-пакетами :)

тото ошибка в RTL(Run Time Library) вылазит.


 
Loginov Dmitry ©   (2008-07-16 19:35) [10]

Еще:
если заменить
raise EMyException.Create("Ошибка при работе функции Proc");
на
raise Exception.Create("Ошибка при работе функции Proc");

то AV не возникает (это поведение как раз и позволило понять что именно происходит :)


 
Loginov Dmitry ©   (2008-07-16 20:41) [11]

Весь прикол в следующем:

Класс EMyException = class(Exception); объявлен в DLL (а не в runtime-пакете), в связи с этим в DLL расположен код, учавстующий в процессе уничтожения объекта. При вызове FreeLibrary(H); этот код выгружается вместе в DLL. При отсутствии кода регенерации исключения в блоке except..end происходит неявное уничтожение объекта исключения. При этом естественно возникнет AV, т.к. кода, ответственного за уничтожение объекта, уже нет.

P.S. данный вывод сделан без анализа ассемблерного кода, если в чем-то неправ, то поправьте.


 
www   (2008-07-16 21:05) [12]

ну так разные классы, один из которых пытается пролезть в ехе, а в ехе он не описан


 
Игорь Шевченко ©   (2008-07-16 23:28) [13]

Ega23 ©   (16.07.08 18:21) [4]

Так обычно и делается


 
Loginov Dmitry ©   (2008-07-17 07:51) [14]

> ну так разные классы, один из которых пытается пролезть
> в ехе, а в ехе он не описан


проблема возникает из-за FreeLibrary(). Если FreeLibrary() не делать, то все работает без ошибок. Причем там даже не важно как скомпилировано/собрано приложение (с пакетами или без) и на какой версии Delphi (EXE может быть на одной, DLL - на другой). Всяко бывало, но к таким ошибкам не приводило.


> Так обычно и делается


Возможно эта технология более универсальная (WinAPI так и работает). Но Delphi предоставляет удобный механизм исключений, который, в общем-то, полностью устраивает, и возвращаться в век каменный как-то особо сильно не хочется.


 
Правильный$Вася   (2008-07-17 10:01) [15]


> проблема возникает из-за FreeLibrary(). Если FreeLibrary()
> не делать, то все работает без ошибок.

это иллюзия


 
int64   (2008-07-17 10:41) [16]

Почему-то вспомнилось:

"...посреди многослойной, переплетенной из еаров, сервисов, коннекторов и пулов структуры сервера приложений, органично врастая в сеть модульной архитектуры, выставив наружу красивые интерфейсы, посылая и получая сообщения, отвечая на эрэмай запросы, словно кипящий поток создавая и уничтожая сотни ентити бинов в десятках распределенных транзакций, мудрый сессионый бин срал в лог эксепшенами."
http://www.rsdn.ru/Forum/message/2730647.flat.aspx


 
wl ©   (2008-07-17 12:55) [17]


> и возвращаться в век каменный как-то особо сильно не хочется.

можно выбросить исключение в зависимости от кода ошибки


 
Mystic ©   (2008-07-18 13:26) [18]

> И EXE и DLL скомпилированы с runtime-пакетами :)

Догда делай пакеты вместо DLL :)

> Loginov Dmitry ©   (16.07.08 20:41) [11]

Где-то так и должно быть...



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

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

Наверх




Память: 0.51 MB
Время: 0.017 c
3-1205316974
иван8511
2008-03-12 13:16
2008.09.07
Не уменьшается размер файла при удалении лишних записей


1-1198227129
Afonya
2007-12-21 11:52
2008.09.07
FastScript доступ к объектам дочерних окон.


15-1216189504
Гость
2008-07-16 10:25
2008.09.07
Replace all


15-1216322321
AlexKniga
2008-07-17 23:18
2008.09.07
Разбиение флоппи-диска на разделы


6-1192982317
JanMihail
2007-10-21 19:58
2008.09.07
Интересный ответ post-запроса