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

Вниз

Проблема с формой в 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;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.031 c
14-1100840649
Danilka
2004-11-19 08:04
2004.12.12
Вот, знакомый прислал


3-1100516912
Алекс
2004-11-15 14:08
2004.12.12
DATAPUMP пример конвертации или статью


4-1099035890
Erik1
2004-10-29 11:44
2004.12.12
Где найти модуль для модальных диалогов?


10-1057851689
sam08
2003-07-10 19:41
2004.12.12
не получается элементарная клиент-серв. с  использ. CORBA


1-1101392626
SV
2004-11-25 17:23
2004.12.12
Изменение позиции формы.