Текущий архив: 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