Форум: "Основная";
Текущий архив: 2004.12.12;
Скачать: [xml.tar.bz2];
ВнизПроблема с формой в DLL Найти похожие ветки
← →
Amadey (2004-11-24 15:20) [0]Доброго времени суток всем уважающим себя гуру!
У меня такой вопросик:
Есть некая библиотека, в ней нескоко функций, в том числе парочка с формами.
Вызов формы стандартный:
try
Form1 := TForm1.Create(Nil);
if Form1.ShowModal = mrOk then
...
except
Form1.Free;
end;
Форма в DLL ведет себя во время работы программы нормально, а при закрытии программы в целом, выдается ошибка типа runtime error 216 at ...
Если не использовать функции с формами, то ошибки не возникает, поэтому появляется предположение, что проблема в форме, точнее при выгрузке её из памяти.
Уважаемые колеги, может кто-нить помочь моему горю, а тобашка кипеть начинает, буду премного благодарен!
← →
Amadey (2004-11-24 15:24) [1]Пардон,
вместо except - ставим finaly
← →
digger © (2004-11-24 16:47) [2]В опциях проекта поставь - Bild with runtime packages. Мне помогло.
← →
Гаврила © (2004-11-24 17:37) [3]Создание формы должно стоять перед try
в остальном проблем быть не должно, ошибка в другом месте
← →
Amoeba © (2004-11-24 17:42) [4]Найди и проштудируй соответствующую статью на сайте "Королевство Delphi": http://www.delphikingdom.com
Там все расписано.
← →
Amadey (2004-11-24 18:36) [5]В соответствующей статье на сайте нихрена не сказано про то, что если убрать один компонент, то все работает.
А любой компонент, связанный с Graphic.dcu на форме генерирует эту ошибку - и что делать?
← →
Юрий Зотов © (2004-11-24 18:58) [6]> Amadey (24.11.04 15:20)
В этом коде все нормально, только поставьте Create ПЕРЕД try.
Ошибка 216 при завершении обычно связана с Memory Management. Если Вы не используете ShareMem, то приведите заголовки всех функций, которые экспортирует DLL, а если используете, то проверьте, стоят ли они в обоих Dpr ПЕРВЫМИ.
← →
Amadey (2004-11-24 19:25) [7]Есть такой файлик:
unit Utils;
interface
// Возвращаем текстовую строку вместо числа
// Value - Число
// Dec - Показывать или нет дробную часть
// Podpis - Показывать или нет подпись
// PodpisStrS(D) - Текстовое значение подписи
function CurrenciToStr(Value: Double; PodpisStrS, PodpisStrD: PChar; const Podpis: Boolean = True; const Dec: Boolean = True): PChar; stdcall; external "Utils.dll";
// Возвращаем текстовую строку даты (аналог родной, но всегда на русском)
// Data - дата
// Full - Полное наименование или краткое ( 1 января 2004г / 1 янв 2004)
// Sclon - сконение месяца (январь / января; март / марта и т.д.)
function DateToStrRus(Data: TDateTime; Full: Boolean = True; Sclon: Boolean = True): PChar; stdcall; external "Utils.dll";
// Возвращаем дату начала года
function DayOfYearFirst(Data: TDateTime): TDateTime; stdcall; external "Utils.dll";
// Возвращаем дату конца года
function DayOfYearLast(Data: TDateTime): TDateTime; stdcall; external "Utils.dll";
// Возвращаем дату начала квартала
function DayOfKvartalFirst(Data: TDateTime): TDateTime; stdcall; external "Utils.dll";
// Возвращаем дату конца квартала
function DayOfKvartalLast(Data: TDateTime): TDateTime; stdcall; external "Utils.dll";
// Возвращаем дату начала месяца
function DayOfMonthFirst(Data: TDateTime): TDateTime; stdcall; external "Utils.dll";
// Возвращаем дату конца месяца
function DayOfMonthLast(Data: TDateTime): TDateTime; stdcall; external "Utils.dll";
// Возвращаем дату начала недели
function DayOfWeekFirst(Data: TDateTime): TDateTime; stdcall; external "Utils.dll";
// Возвращаем дату конца недели
function DayOfWeekLast(Data: TDateTime): TDateTime; stdcall; external "Utils.dll";
// Возвращаем период значений (в переменных DateFirst, DateLast)
// DateFirst, DateLast - даты начала окончания периода
// Caption - заголовок окна
// TextVid - 1: ответ текстом (по умолчанию)
// 2: ответ в формате даты
function ChoosePeriod(var DateFirst, DateLast: TDateTime; Caption: PChar; TextVid: Integer = 1): PChar; stdcall; external "Utils.dll";
// Возвращаем текстовое значение дня недели
// Full - Полное название или краткое ("Пятница" / "Пт")
// Upper - Первая буква заглавная ("Пятница" / "пятница")
function DayOfWeekRus(Data: TDateTime; Full: Boolean = True; Upper: Boolean = True): PChar; stdcall; external "Utils.dll";
implementation
end.
← →
Юрий Зотов © (2004-11-24 21:14) [8]> Amadey (24.11.04 19:25) [7]
Насколько я понял, длинные строки и динамические массивы в параметрах функций не используются, поэтому не используется и ShareMem.
В таком случае можно предположить, что ошибка 216 возникает из-за неверной работы с PChar (память выделяется в EXE, а освобождается в DLL, либо наоборот). В частности, очень подозрительно выглядят функции, возвращающие PChar своим результатом (CurrenciToStr и другие).
Приведите, например, код реализации CurrenciToStr в DLL и код ее вызова из EXE.
← →
Amadey (2004-11-25 08:53) [9]С этими функциями все впорядке, вываливается при работе с формой
function ChoosePeriod(var DateFirst, DateLast: TDateTime; Caption: PChar; TextVid: Integer = 1): PChar; stdcall; external "Utils.dll";
А если форму не использовать, то excepta не возникает
← →
Юрий Зотов © (2004-11-25 15:08) [10]> Amadey (25.11.04 08:53) [9]
Еще раз.
1. В приведенных Вами кусках кода ощибок нет (за исключением того, что Create должно быть перед try, но это к сабжу не относится). Она (или они) где-то в другом месте.
2. С точки зрения ошибки 216 ОЧЕНЬ подозрительно выглядят функции, имеющие в параметрах PChar и, ОСОБЕННО, возвращающие PChar. Если память под такой параметр или результат выделяется в одном модуле, а освобождается в другом, то именно это с ОЧЕНЬ большой вероятностью и есть причина ошибки 216 при закрытии программы.
3. Пример кода реализации такой функции и кода ее вызова Вы не привели, а из приведенного Вами кода не видно, где выделяется и где освобождается память под PChar. Поэтому сказать что-то более конкретное нельзя.
← →
Amadey (2004-11-26 17:02) [11]Всем спасибо, тема закрыта.
Для тех кому интересно!
Проблема заключается не в DLL и не в программе вызова, с этой точки зрения все нормально!
Проблема с XPManifest, а точнее с файлом от Borland под именем themes.dcu (pas).
При нахождении оного на вызывающей форме или файла манифеста в каталоге с программой, происходит выделение памяти под объекты для формы в Dll и затем некорректное его освобождение.
Пробовал на разных машинах запускать: если есть XP с включенными темами рабочего стола, тогда происходит описанная ошибка, нет тем или другая операционка - ошибки нет.
РЕШЕНИЕ
В файле Themes.pas исправить ошибку освобождения памяти и перекомпилировать! После этого проблема исчезает!
Всем спасибо за помощь.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.12.12;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.041 c