![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблема с формой в DLL [D7, WinXP]
Amadey © (2004-11-24 15:20:00)Доброго времени суток всем уважающим себя гуру!
У меня такой вопросик:
Есть некая библиотека, в ней нескоко функций, в том числе парочка с формами.
Вызов формы стандартный:
try
Form1 := TForm1.Create(Nil);
if Form1.ShowModal = mrOk then
...
except
Form1.Free;
end;
Форма в DLL ведет себя во время работы программы нормально, а при закрытии программы в целом, выдается ошибка типа runtime error 216 at ...
Если не использовать функции с формами, то ошибки не возникает, поэтому появляется предположение, что проблема в форме, точнее при выгрузке её из памяти.
Уважаемые колеги, может кто-нить помочь моему горю, а тобашка кипеть начинает, буду премного благодарен!
Amadey (2004-11-26 17:02:00) [1]Всем спасибо, тема закрыта.
Для тех кому интересно!
Проблема заключается не в DLL и не в программе вызова, с этой точки зрения все нормально!
Проблема с XPManifest, а точнее с файлом от Borland под именем themes.dcu (pas).
При нахождении оного на вызывающей форме или файла манифеста в каталоге с программой, происходит выделение памяти под объекты для формы в Dll и затем некорректное его освобождение.
Пробовал на разных машинах запускать: если есть XP с включенными темами рабочего стола, тогда происходит описанная ошибка, нет тем или другая операционка - ошибки нет.
РЕШЕНИЕ
В файле Themes.pas исправить ошибку освобождения памяти и перекомпилировать! После этого проблема исчезает!
Всем спасибо за помощь.
Юрий Зотов (2004-11-25 15:08:00) [2]> Amadey (25.11.04 08:53) [9]
Еще раз.
1. В приведенных Вами кусках кода ощибок нет (за исключением того, что Create должно быть перед try, но это к сабжу не относится). Она (или они) где-то в другом месте.
2. С точки зрения ошибки 216 ОЧЕНЬ подозрительно выглядят функции, имеющие в параметрах PChar и, ОСОБЕННО, возвращающие PChar. Если память под такой параметр или результат выделяется в одном модуле, а освобождается в другом, то именно это с ОЧЕНЬ большой вероятностью и есть причина ошибки 216 при закрытии программы.
3. Пример кода реализации такой функции и кода ее вызова Вы не привели, а из приведенного Вами кода не видно, где выделяется и где освобождается память под PChar. Поэтому сказать что-то более конкретное нельзя.
Amadey (2004-11-25 08:53:00) [3]С этими функциями все впорядке, вываливается при работе с формой
function ChoosePeriod(var DateFirst, DateLast: TDateTime; Caption: PChar; TextVid: Integer = 1): PChar; stdcall; external 'Utils.dll';
А если форму не использовать, то excepta не возникает
Юрий Зотов (2004-11-24 21:14:00) [4]> Amadey (24.11.04 19:25) [7]
Насколько я понял, длинные строки и динамические массивы в параметрах функций не используются, поэтому не используется и ShareMem.
В таком случае можно предположить, что ошибка 216 возникает из-за неверной работы с PChar (память выделяется в EXE, а освобождается в DLL, либо наоборот). В частности, очень подозрительно выглядят функции, возвращающие PChar своим результатом (CurrenciToStr и другие).
Приведите, например, код реализации CurrenciToStr в DLL и код ее вызова из EXE.
Amadey (2004-11-24 19:25:00) [5]Есть такой файлик:
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 18:58:00) [6]> Amadey (24.11.04 15:20)
В этом коде все нормально, только поставьте Create ПЕРЕД try.
Ошибка 216 при завершении обычно связана с Memory Management. Если Вы не используете ShareMem, то приведите заголовки всех функций, которые экспортирует DLL, а если используете, то проверьте, стоят ли они в обоих Dpr ПЕРВЫМИ.
Amadey (2004-11-24 18:36:00) [7]В соответствующей статье на сайте нихрена не сказано про то, что если убрать один компонент, то все работает.
А любой компонент, связанный с Graphic.dcu на форме генерирует эту ошибку - и что делать?
Amoeba (2004-11-24 17:42:00) [8]Найди и проштудируй соответствующую статью на сайте "Королевство Delphi": http://www.delphikingdom.com
Там все расписано.
Гаврила (2004-11-24 17:37:00) [9]Создание формы должно стоять перед try
в остальном проблем быть не должно, ошибка в другом месте
digger (2004-11-24 16:47:00) [10]В опциях проекта поставь - Bild with runtime packages. Мне помогло.
Amadey (2004-11-24 15:24:00) [11]Пардон,
вместо except- ставим finaly