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

Вниз

Как достать фрейм из 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;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.025 c
1-1129094952
SANEK_10289
2005-10-12 09:29
2005.11.06
Помогите пожалуйста... Я из реестра беру имя пользователя...


11-1110634509
Watcher
2005-03-12 16:35
2005.11.06
Transparent


2-1128957890
boo
2005-10-10 19:24
2005.11.06
есть программа, в ней есть окно, в которое выводятся числа от 0


1-1129040484
PAI
2005-10-11 18:21
2005.11.06
Как создать группу?


1-1129278586
Prohodil Mimo
2005-10-14 12:29
2005.11.06
Как установить фокус на компонент?