![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Ошибка при использовании DLL [D7, Win95/98, WinXP]
Gloomer © (2005-02-09 08:51:00)Есть DLL с функцией (привожу в упрощенной форме, но вполне работоспособной)
library MyDLL;
function MyFunc:string;
begin
result:='aaa';
end;
exports MyFunc;
end.
Вызываю эту функцию, причем с явной загрузкой DLL:
program MyProg;
uses Windows;
type TMyFunc=function:string;
var DLL: THandle;
MyFunc:TMyFunc;
s:string;
begin
DLL := LoadLibrary('MyDLL');
if DLL<>0 then
begin
@MyFunc:=GetProcAddress(DLL,'MyFunc');
if @MyFunc<>nil
then s:=MyFunc;
FreeLibrary(DLL);
end;
s:=''+s; //добавлено для оптимизатора
end.
Всё прекрасно работает, функция возвращает значение, FreeLibrary возвращает true, но после выполнения последней строки кода (не важно какой) при завершении работы выскакивает ошибка Runtime error 216
C чем это может быть связано?
При неявной загрузке DLL ошибки нет
program MyProg1;
function MyFunc:string;external'mydll.dll';
var s:string;
begin
s:=MyFunc;
end.
При замене функции на процедуру также ошибки нет.
Digitman (2005-02-09 09:26:00) [1]
> почему при неявной загрузке DLL нет ошибки?
потому что "выгрузка ДЛЛ" в этом случае происходит позже чем отработают все неявные процедуры финализации, т.е. в момент ExitProcess
> И ShareMem также не нужен?
ShareMem нужен когда вызывающий и вызываемый проекты собраны с разными опциями использования ран-тайм пакетов
если оба проекта используют ран-тайм пакеты, ShareMem в принципе не нужен, ссылка на него НЕ ДОЛЖНА фигурировать ни в том ни в другом проекте .. либо, вне зависимости от этой опции, ShareMem должен обязательно присутствовать и там и там
Gloomer (2005-02-09 09:12:00) [2]>КаПиБаРа © (09.02.05 08:55) [1]
Спасибо, помогло...
>Digitman © (09.02.05 09:06) [2]
Спасибо за подробный ответ, но хотелось бы знать, а почему при неявной загрузке DLL нет ошибки? И ShareMem также не нужен? Или Delphi сама настолько умная, что использует без моего согласия?
Digitman (2005-02-09 09:06:00) [3]
> C чем это может быть связано?
хотя бы с тем что стр.константа 'aaa' располагалась в модуле MyDLL
после выполнения строчки s:=MyFunc переменная s стала ссылаться на адрес местонахождения этой константы в АП тек.процесса
далее ты выгружаешь модуль MyDLL по FreeLibrary, и константа перестает существовать, хотя переменная s по-прежнему существует и по-прежнему ссылается на эту константу, которая уже не существует.
далее ты завершаешь работу приложения, при этом выполняется сгенерированный компилятором неявный код финализации, в ходе работы которого происходит попытка освободить память, на которую ссылаются еще существующие на этот момент дин.структуры, в т.ч. и стр.переменная s.. но поскольку область памяти, которая ранее (пока была загружена твоя библ-ка) была распределена под стр.константу и на которую на этот момент ссылается переменная s, не существует, попытка "освобождения" этой памяти терпит неожиданный крах, что и фиксируется отказом с диагн.сообщением Runtime error 216
КаПиБаРа (2005-02-09 08:55:00) [4]F1 - ShareMem