Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.11.06;
Скачать: [xml.tar.bz2];

Вниз

Как достать фрейм из bpl ?   Найти похожие ветки 

 
BFG9k ©   (2005-10-07 16:02) [0]

Создаю пакет, включаю в него unit с фреймом.

Помпилирую пакет ,получаю bpl.

В другом проекте загружаю bpl  с помощью LoadPackage. Можно ли достать фрейм из bpl и кинуть на форму этого проекта ?


 
REA   (2005-10-07 17:56) [1]

Можно поступить следующими способами:
1) Экспортировать функцию - конструктор фрейма, возвращающую фрейм (базовый класс)
2) Зарегистрировать в bpl класс при помщи RegisterClass, найти его в программе и создать на основе метакласса объект.


 
BFG9k ©   (2005-10-10 16:24) [2]

Попробовал оба варианта.

1) Не нашел как экспортировать функцию из пакета. Можно ли вообще это сделать (в contains указываются только модули)? Попробовал сделать то же самое с DLL. Получилось вернуть Handle создаваемой формы, но не фрейма. Как только происходит обращение к Parent - исключение EInvalidOperation. При попытке вернуть экземпляр формы/фрейма - то же самое.
Привожу код DLL :

function CreateFrame(AParent:THandle):THandle;
begin
  Form1:=TForm1.CreateParented(AParent);
  Result:=Form1.Handle;
end;

procedure DestroyFrame;
begin
  Form1.Free;
end;

Exports
  CreateFrame name "CreateFrame",
  DestroyFrame name "DestroyFrame",
begin
end.


С фреймом то же самое не проходит - вылетает на CreateParented. Подозреваю, что TForm/TFrame вернуть невозможно в принципе :(

2) Делаю RegisterClass в разделе initialization модуля с фреймом. Секция выполняется - проверял. Загружаю пакет - FindClass ничего не находит.


 
BFG9k ©   (2005-10-10 16:40) [3]

Нашел неплохую статью на эту тему : http://www.delphimaster.ru/articles/bdform/index.html

Правда все как-то через анус реализованно (хакерскими методами, я имею в виду).


 
Reindeer Moss Eater ©   (2005-10-10 17:05) [4]

LoadPackage
EnumModules
Затем ищи с пом. GetProcAddress в модулях процедуру с предопределенным тобой именем: "@" + <Имя_Модуля> + "@" + <Имя_процедуры> + "$qqrv"
Она тебе и создаст нужный фрейм.


 
BFG9k ©   (2005-10-11 13:28) [5]

Спасибо. Никогда не подозревал, что раздел Exports может существовать прямо в модуле фрейма.

Однако не все так хорошо, как могло бы показаться. Попытался создать фрейм с одной кнопкой. Фрейм создался. В начале вылезла ошибка : Cannot assign TFont to TFont. При уничтожении фрейма - Access Violation.

Нашел статью о загрузке обьектов из DLL : http://www.delphimaster.ru/articles/book/Chap09.pdf

Смущает пункт 3 требований к DLL :

"Экспортируемый объект должен быть определен как в DLL , так и в вызывающем приложении с помощью методов, определенных в том же порядке."

2 раза определять объект?! Смысл применения DLL в таком случае пропадает.

Обнадеживает следующая фраза :

"Используемый подход применяется в весьма специфических ситуациях, и , как правило, такого же эффекта можно достичь путем применения пакетов и интерфейсов".

Применение энтерфейсов при взаимодействии Delphi с Delphi не обосновано. Я применяю пакеты, к сожалению в статье не сказано, как их применять :(


 
REA   (2005-10-11 13:30) [6]

Скомпилировать все с включенными run-time packages.


 
BFG9k ©   (2005-10-11 14:19) [7]

Точно!

И последний вопрос: как лучше уничтожать созданные экземпляры фрейма ? При вызове Unload Package возникает Access Violation, если фрейм не уничтожить. Просто написать в основной программе Frame1.Free - не проходит. С одним экземпляром проблем нет - уничтожать его в DLL. Для нескольких экземпляров необходимо уже вести их индексацию в DLL. Можно ли как-либо уничтожать экземпляр фрейма, имея только ссылку на него ?


 
Reindeer Moss Eater ©   (2005-10-11 14:37) [8]

Можно ли как-либо уничтожать экземпляр фрейма, имея только ссылку на него ?

<ссылка на него>.Free


 
BFG9k ©   (2005-10-11 15:04) [9]

Если делать это в главной программе, то при вызове UnloadPackage имеем Access Violation. Ладно, сделаю индексацию динамическим массивом, это не долго.


 
Reindeer Moss Eater ©   (2005-10-11 16:09) [10]

Если делать это в главной программе,

Нет никакой разницы где это делать.
Если у тебя AV, значит у тебя либо невалидная ссылка, либо ошибка в программе.


 
BFG9k ©   (2005-10-11 17:19) [11]

Да, видимо у меня невалидная ссылка.

Делаю следующим образом:


procedure TForm1.FormCreate(Sender: TObject);
var Flags:integer;
begin
  M:=LoadPackage("Packages\Package1.bpl");

  @FrameConstructor:=GetProcAddress(M,"CreateFrame");

  if Assigned(FrameConstructor) then
      Frame1:=FrameConstructor(Self,Self);//Первое - Owner , второе - Parent
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Frame1.Free;//можно не освобождать - результат тот же
  UnloadPackage(M);//возникает Access Violation
end;


  Так вот, AV не возникает, если в пакете сделать следующее :


implementation

var Frame1:TFrame1;

{$R *.dfm}

function CreateFrame(AOwner:TComponent;AParent:TWinControl):TFrame;
begin
  Frame1:=TFrame1.Create(AOwner);
  Frame1.Parent:=AParent;
  Result:=Frame1;
end;

exports
  CreateFrame name "CreateFrame";
initialization
  Frame1:=nil;
finalization
  if Assigned(Frame1) then
     Frame1.Free; // в этом случае выгрузка происходит корректно
end.


Frame1 в пакете и программе - разные указатели, но на одну и ту же структуру (просто имена совпадают).


 
REA   (2005-10-12 10:57) [12]

Owner у Frame форма, она его и убъет.
Frame1.Free уже может работать по невалидной ссылке.


 
BFG9k ©   (2005-10-12 14:56) [13]

Но AV возникает как раз в том случае, если я НЕ убиваю фрейм в finalization (даже если я нигде его не убиваю). Вот я и думаю, к чему бы это.


 
REA   (2005-10-12 15:55) [14]

Вариант 1:
Переменная M где-то портится.

Вариант 2:
Обработчики фрейма могут быть в BPL. При попытке вызова обработчика при выгруженной BPL - AV.

Вот это ничего не даст, т.к. во Free и так проверяется Assigned.
if Assigned(Frame1) then
    Frame1.Free;



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2005.11.06;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.032 c
14-1128796474
mmms
2005-10-08 22:34
2005.11.06
Примечание для программистов.


14-1129180394
Ega23
2005-10-13 09:13
2005.11.06
С днем рождения! 13 октября


3-1127564247
erika
2005-09-24 16:17
2005.11.06
формирование запроса


2-1129070139
snowkam
2005-10-12 02:35
2005.11.06
Консоль + BD


14-1129612619
Ega23
2005-10-18 09:16
2005.11.06
С днем рождения! 18 октября





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