Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.02.20;
Скачать: [xml.tar.bz2];

Вниз

Ошибка при использовании 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.45 MB
Время: 0.041 c
14-1106817355
Vaitek
2005-01-27 12:15
2005.02.20
Школьная геометрия


1-1107436283
JohnKorsh
2005-02-03 16:11
2005.02.20
Возможно ли стирание программой своего EXE файла ?


1-1107506780
Zilog
2005-02-04 11:46
2005.02.20
LoadFromResourceName


1-1107441756
Пчелка
2005-02-03 17:42
2005.02.20
Русские надписи на кнопках в MessageDlg


14-1107249320
Ozone
2005-02-01 12:15
2005.02.20
Настройка маршрутизаторов (Cisco)





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский