запуск форм из Dll-и.

Модераторы: Duncon, Naeel Maqsudov, Хыиуду, Игорь Акопян

Ответить
BBB
Сообщения: 1272
Зарегистрирован: 27 дек 2005, 13:37

14 июн 2007, 11:48

Если создать новое приложение в Дельфи (у меня Delphi 6), то автоматом создастся форма (диалоговое окно) и основной файл dpr приложения, где будет текст типа:

Код: Выделить всё

begin
  Application.Initialize;
  Application.CreateForm (TForm1, Form1);
  Application.Run;
end.
А если я хочу сделать следующее. Не делать EXE, а создать DLL, из которой проэкспортировать процедцру, в которой вызывается некая форма.
Как создать DLL ипроэкспортировать функцию - это понятно (обсуждалось в этом же разделе :) )

А вот как вызвать запуск формы?
Попробовал сделать так (RunForm - это и есть экспортируемая процедура):

Код: Выделить всё

procedure RunDiagram; stdcall;
var iRes : integer;
var
    vMainForm : TMainForm;
begin

  Application.Initialize;
  Application.CreateForm (TMainForm, vMainForm);

  iRes := vMainForm.ShowModal ();

  vMainForm.Release ();

  exit;

end;
Но что-то как-то после закрытия формы выскакивает исключение. Причем, как-то "плавающим образом". на одном компьютере выскакивает, на другом нет. Если, например, после vMainForm.Release (); написать ShowMessage ('TEST');, то сообщение об исключении не выскакивает. Если вставить отладочную печать (тоже ShowMessage ('FormDestroy')) в TForm1.FormDestroy (), то: (при отсутствии ShowMessage ('TEST')) :
1) на том компьютере, где ранее исключения не было, оно появляется два раза и исключение возникает;
2) на другом компьютере вообще ни разу не появляется.

Если же ShowMessage ('TEST') наличествeт, то на обоих компьютерах все хорошо: оба сообщения ('FormDestroy' и 'TEST') появляются по разу.

Скорее всего, из такого непредсказуемого поведения можно сделать вывод, что где-то запарывается стек. Вот и интересно, я как-то неправильно вызываю эту форму из процедуры DLL-application-а?

Кто-нибудь пробовал делать что-либо подобное?

Заранее спасибо.
BBB
Сообщения: 1272
Зарегистрирован: 27 дек 2005, 13:37

14 июн 2007, 12:06

Дубль 2.

Похоже, я что-то принципиально не так делаю.
Сделал вообще пустую форму, исключение не пропадает. Т.е., точнее "на одном" компьютере (там, к слову, Delphi установлен) исключения нет. А "на другом" (там Delphi не установлен) оно по-прежнему выскакивает (текст: "Исключение неизвестное программное исключение (0x0eedfade) в приложении по адресу 0x793aa4e1"). При наличии ShowMessage ('TEST') все завершается без сообщений.

Текст модуля формы:

Код: Выделить всё

unit MainForm_U;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, ExtCtrls;


type
  TMainForm = class(TForm)

  private
    { Private declarations }

  public
    { Public declarations }

  end;

var
  vMainForm : TMainForm;


 //============================================
               implementation
 //============================================

{$R *.dfm}


end.
DFM-файл:

Код: Выделить всё

object MainForm: TMainForm
  Left = 27
  Top = 46
  Width = 750
  Height = 514
  Caption = #1044#1080#1072#1075#1088#1072#1084#1099
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
end
BBB
Сообщения: 1272
Зарегистрирован: 27 дек 2005, 13:37

14 июн 2007, 12:54

Походу, проблема в операторе vMainForm.Release ();

Нашел текст "Разработка DLL в среде Borland Delphi", там вместо этого используется vMainForm.Free (). (И вместо Application.CreateForm (TMainForm, vMainForm); там используется vMainForm := TMainForm.Create (Application);, но предположил, что это несущественно [хотя тоже попробовал])

Попробовал - падения прекратились.
Хотя не совсем понятно, почему было такое странное поведение с использоваением Release. Почитал help, Там вроде ничего "угрожающего" не написано... :confused:
Аватара пользователя
Игорь Акопян
Сообщения: 1419
Зарегистрирован: 13 окт 2004, 17:11
Откуда: СПБ
Контактная информация:

14 июн 2007, 17:56

а что мешало создать dll xthtp файл/новый... там какой-то важный коментарий вверху вроде был... что-то про менеджер памяти чтоль....
Изображение
BBB
Сообщения: 1272
Зарегистрирован: 27 дек 2005, 13:37

15 июн 2007, 10:13

Игорь Акопян писал(а):а что мешало создать dll xthtp файл/новый... там какой-то важный коментарий вверху вроде был... что-то про менеджер памяти чтоль....
Так и делал. Комментарий читал. Но это совсем другая история. Там хинт на тот случай, если предполагается выделение памяти в одной DLL, а освобождение - в другой. Перевод такой (найдено в одной из интернетовских статей):

{ Существенное замечание об управлении памятью в DLL: Если DLL экспортирует функции со строковыми параметрами или возвращающие строковые значения, модуль ShareMem надо указывать в разделе Uses библиотеки и проекта первым. Это касается любых строк, передаваемых как в DLL, так и из нее, даже если они размещаются внутри записей или объектов. Модуль ShareMem служит интерфейсом менеджера разделяемой памяти DELPHIMM.DLL (в моем комментарии стояло дргое имя: BORLNDMM.DLL - BBB), который должен разворачиваться одновременно с данной DLL. Чтобы избежать применения DELPHIMM.DLL, строковую информацию можно передавать с помощью параметров
типа PChar или ShortString. }
Ответить