Форум: "Основная";
Текущий архив: 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.052 c