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

Вниз

Ошибка при использовании DLL   Найти похожие ветки 

 
Gloomer ©   (2005-02-09 08:51) [0]

Есть 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.


При замене функции на процедуру также ошибки нет.


 
КаПиБаРа ©   (2005-02-09 08:55) [1]

F1 - ShareMem


 
Digitman ©   (2005-02-09 09:06) [2]


> C чем это может быть связано?


хотя бы с тем что стр.константа "aaa" располагалась в модуле MyDLL

после выполнения строчки s:=MyFunc переменная s стала ссылаться на адрес местонахождения этой константы в АП тек.процесса

далее ты выгружаешь модуль MyDLL по FreeLibrary, и константа перестает существовать, хотя переменная s по-прежнему существует и по-прежнему ссылается на эту константу, которая уже не существует.

далее ты завершаешь работу приложения, при этом выполняется сгенерированный компилятором неявный код финализации, в ходе работы которого происходит попытка освободить память, на которую ссылаются еще существующие на этот момент дин.структуры, в т.ч. и стр.переменная s.. но поскольку область памяти, которая ранее (пока была загружена твоя библ-ка) была распределена под стр.константу и на которую на этот момент ссылается переменная s, не существует, попытка "освобождения" этой памяти терпит неожиданный крах, что и фиксируется отказом с диагн.сообщением Runtime error 216


 
Gloomer ©   (2005-02-09 09:12) [3]

>КаПиБаРа ©   (09.02.05 08:55) [1]
Спасибо, помогло...

>Digitman ©   (09.02.05 09:06) [2]
Спасибо за подробный ответ, но хотелось бы знать, а почему при неявной загрузке DLL нет ошибки? И ShareMem также не нужен? Или Delphi сама настолько умная, что использует без моего согласия?


 
Digitman ©   (2005-02-09 09:26) [4]


> почему при неявной загрузке DLL нет ошибки?


потому что "выгрузка ДЛЛ" в этом случае происходит позже чем отработают все неявные процедуры финализации, т.е. в момент ExitProcess


> И ShareMem также не нужен?


ShareMem нужен когда вызывающий и вызываемый проекты собраны с разными опциями использования ран-тайм пакетов

если оба проекта используют ран-тайм пакеты, ShareMem в принципе не нужен, ссылка на него НЕ ДОЛЖНА фигурировать ни в том ни в другом проекте .. либо, вне зависимости от этой опции, ShareMem должен обязательно присутствовать и там и там



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

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

Наверх




Память: 0.48 MB
Время: 0.03 c
4-1104321154
TankMan
2004-12-29 14:52
2005.02.20
Вот почему не работает WMI при установке винды?


4-1104954636
Arnold
2005-01-05 22:50
2005.02.20
Как узнать список файлов в выбранной директории?


1-1107778346
-= Demon =-
2005-02-07 15:12
2005.02.20
Как определить, что файл записан на диск полностью


14-1106881694
Думкин
2005-01-28 06:08
2005.02.20
С Днем Рождения! 28 января


1-1107347080
Dmitry_04
2005-02-02 15:24
2005.02.20
Скинообразная форма непрямоугольногоя