Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.042 c
4-1098865873
Chris
2004-10-27 12:31
2004.12.12
Создание списка PCI устройств


1-1101799104
Progh
2004-11-30 10:18
2004.12.12
Сохранения TListView в виде HTML


8-1095138488
resha
2004-09-14 09:08
2004.12.12
Обработка звука!!!


3-1100069354
first_may
2004-11-10 09:49
2004.12.12
Ошибка...


1-1101856183
bulanov
2004-12-01 02:09
2004.12.12
Притормаживание при загрузке рисунка





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский