-
Loginov Dmitry © (16.07.08 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 © (16.07.08 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 © (16.07.08 18:10) [2]что-то типа для передачи строк из dll в exe нужно подключить некий модуль?
-
Поросенок Винни-Пух © (16.07.08 18:13) [3]потому что возбуждено в длл, а обращение к строке идет в хост аппликейшен (а шаремема нет)
Exception = class(TObject)
.....
property Message: string read FMessage write FMessage; -
Я бы ErrorCode из Dll возвращал, а не исключение генерил.
Но это так, к слову... -
Mystic © (16.07.08 18:27) [5]Потому что в DLL своей класс Exception, а в твоем приложении свой.
-
Dimka Maslov © (16.07.08 19:03) [6]Можно ещё попробовать сгенерировать исключение в библиотеке, написанной на С.
-
Loginov Dmitry © (16.07.08 19:18) [7]> что-то типа для передачи строк из dll в exe нужно подключить
> некий модуль?
> Потому что в DLL своей класс Exception, а в твоем приложении
> свой.
И EXE и DLL скомпилированы с runtime-пакетами :) -
Loginov Dmitry © (16.07.08 19:19) [8]ShowMessage(E.Message);
отрабатывает верно, показывает что и должно. Ошибка возникает после. -
@!!ex © (16.07.08 19:22) [9]> скомпилированы с runtime-пакетами :)
тото ошибка в RTL(Run Time Library) вылазит. -
Loginov Dmitry © (16.07.08 19:35) [10]Еще:
если заменитьraise EMyException.Create('Ошибка при работе функции Proc');
наraise Exception.Create('Ошибка при работе функции Proc');
то AV не возникает (это поведение как раз и позволило понять что именно происходит :) -
Loginov Dmitry © (16.07.08 20:41) [11]Весь прикол в следующем:
КлассEMyException = class(Exception);
объявлен в DLL (а не в runtime-пакете), в связи с этим в DLL расположен код, учавстующий в процессе уничтожения объекта. При вызовеFreeLibrary(H);
этот код выгружается вместе в DLL. При отсутствии кода регенерации исключения в блокеexcept..end
происходит неявное уничтожение объекта исключения. При этом естественно возникнет AV, т.к. кода, ответственного за уничтожение объекта, уже нет.
P.S. данный вывод сделан без анализа ассемблерного кода, если в чем-то неправ, то поправьте. -
www (16.07.08 21:05) [12]ну так разные классы, один из которых пытается пролезть в ехе, а в ехе он не описан