Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Plugin 
:(
    Опции темы
<Spawn>
Дата 28.6.2003, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Око кары:)
****


Профиль
Группа: Экс. модератор
Сообщений: 2776
Регистрация: 29.1.2003
Где: Екатеринбург

Репутация: 44
Всего: 64



Хочется сделать что то типа плагинов к своим прогам, но вот не поиму как, например, добавить из ДЛЛ еще один TTabSheet в TPageControl своей проги? Например, использование подобного кода приводит к ошибке.

Код
Library TestDLL;
uses
 SysUtils,
 Classes,
 ShareMem,
 ComCtrls;

{$R *.res}

function GetPluginControl:TTabSheet;export;stdcall;
begin
with Result.Create(nil) do
Caption:='TestTabSheet';
end;

exports
GetPluginControl;


Это сообщение отредактировал(а) <Spawn> - 28.6.2003, 10:25


--------------------
"Для некоторых людей программирование является такой же внутренней потребностью, подобно тому, как коровы дают молоко, или писатели стремятся писать" - Николай Безруков.
PM MAIL ICQ   Вверх
&-ray
Дата 28.6.2003, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 406
Регистрация: 15.4.2003
Где: Казахстан, г Аста на

Репутация: нет
Всего: нет



Скорее всего ошибка здесь:

Цитата
Result.Create(nil)


Почему nil confused.gif
Здесь по-моему должен быть владелец твоего ttabsheet типа tpagecontrol

А вообще в help'е в Делфях сказано так

Цитата
When creating tab sheets at runtime, use the PageControl property to insert them into a page control object.
, т.е. мути непосредственно все через pagecontrol.




--------------------
"Совсем неважно от чего помрешь, ведь куда важнее - для чего родился..." С.Б.

--------------------
И снова мышь беру я в руки
Куда иду? - Конечно в сруки!
PM MAIL WWW   Вверх
<Spawn>
Дата 28.6.2003, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Око кары:)
****


Профиль
Группа: Экс. модератор
Сообщений: 2776
Регистрация: 29.1.2003
Где: Екатеринбург

Репутация: 44
Всего: 64



Ну к примеру, если я передам PageControl по ссылке то вылетает Access Vialetion
Код
procedure GetPluginControl(var PageCtrl:TPageControl);export;stdcall;
var
TabSheet:TTabSheet;
begin
with TabSheet.Create(PageCtrl) do
Caption:='TestTabSheet';
end;

exports
GetPlugin;


Это сообщение отредактировал(а) <Spawn> - 28.6.2003, 13:35


--------------------
"Для некоторых людей программирование является такой же внутренней потребностью, подобно тому, как коровы дают молоко, или писатели стремятся писать" - Николай Безруков.
PM MAIL ICQ   Вверх
<Spawn>
Дата 28.6.2003, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Око кары:)
****


Профиль
Группа: Экс. модератор
Сообщений: 2776
Регистрация: 29.1.2003
Где: Екатеринбург

Репутация: 44
Всего: 64



Если же передавать не по ссылке PageControl, то возникает ошибка EStackOverflow.

Это сообщение отредактировал(а) <Spawn> - 28.6.2003, 13:40


--------------------
"Для некоторых людей программирование является такой же внутренней потребностью, подобно тому, как коровы дают молоко, или писатели стремятся писать" - Николай Безруков.
PM MAIL ICQ   Вверх
dm9
Дата 28.6.2003, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дмитрий Копытин
****


Профиль
Группа: Vingrad developer
Сообщений: 3876
Регистрация: 22.7.2002
Где: Москва

Репутация: 6
Всего: 137



ИМХО, так и не должно работать.

Кто ж вызывает так метод Create?

Надо, насколько я знаю, так:

Код
Library TestDLL;

uses
SysUtils,
Classes,
ShareMem,
ComCtrls;

{$R *.res}

function GetPluginControl:TTabSheet;export;stdcall;
begin
  Result := TTabSheet.Create(nil) do
  Result.Caption := 'TestTabSheet';
end;

exports
  GetPluginControl;


Только:
1) Не забывай освобождать память. nil дело плохое. Лучше передавай в процедуру того, кто будет владельцем - потом проблем меньше будет.
2) Не уверен, что строка Result.Caption := 'TestTabSheet'; будет работать. Хотя, если откомпилирует, то всё ОК. Просто я не уверен, то можно так обращаться к переменное Result. Хотя хз. Делфей нет, проверить не могу.
3) Если передашь в процедуру того, кто будет Parent'ом, проблем будет меньше: он может быть Owner'ом и сразу скажешь, что он Parent. (Хотя нужен ли TabSheet'у Parent? Не помню confused.gif )
smile.gif

Это сообщение отредактировал(а) dm9 - 28.6.2003, 14:17
PM MAIL ICQ   Вверх
<Spawn>
Дата 28.6.2003, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Око кары:)
****


Профиль
Группа: Экс. модератор
Сообщений: 2776
Регистрация: 29.1.2003
Где: Екатеринбург

Репутация: 44
Всего: 64



Дак записи типа
Result:=TTabSheet.Create(nil)
и
with Result.Create(nil) do

это одно и то же smile.gif


--------------------
"Для некоторых людей программирование является такой же внутренней потребностью, подобно тому, как коровы дают молоко, или писатели стремятся писать" - Николай Безруков.
PM MAIL ICQ   Вверх
dm9
Дата 28.6.2003, 14:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дмитрий Копытин
****


Профиль
Группа: Vingrad developer
Сообщений: 3876
Регистрация: 22.7.2002
Где: Москва

Репутация: 6
Всего: 137



Тьфу ты, сорри. smile.gif Крыша едет. Конечно, у тебя же там TTabSheet как результат ф-ции выдаётся.
PM MAIL ICQ   Вверх
dm9
Дата 28.6.2003, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дмитрий Копытин
****


Профиль
Группа: Vingrad developer
Сообщений: 3876
Регистрация: 22.7.2002
Где: Москва

Репутация: 6
Всего: 137



Я тут поразмышлял немного и понял, что был прав. Не одно это и то же. Ты пишешь код, эквивалентный этому:

Код
function GetPluginControl:TTabSheet;export;stdcall;
begin
  GetPluginControl.Create(nil);
  GetPluginControl.Caption:='TestTabSheet';
end;


Такое не работает по определению.

Тогда уж так делай:

Код
function GetPluginControl:TTabSheet;export;stdcall;
begin
  Result := TTabSheet.Create (nil);
  Result.Caption := 'TestTabSheet';
end;


У тебя ошибка возникает при вызове ф-ции dll.
В моём коде такой ошибки нет.
Другое дело, что потом, уже в теле основной программы, я не могу ничего сделать с полученным указателем

TabSheet := Proc; - работает
TabSheet.PageControl := PageControl1; - возникает ошибка (cannot assign TFont to TFont)

В чём дело - не пойму. Может, ещё какие директивы надо указывать? Я с dll очень мало работал...
PM MAIL ICQ   Вверх
&-ray
Дата 28.6.2003, 22:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 406
Регистрация: 15.4.2003
Где: Казахстан, г Аста на

Репутация: нет
Всего: нет



2<Spawn>
А вот так не пробовал confused.gif:

Цитата
procedure GetPluginControl(var PageCtrl:TPageControl);export;stdcall;
var
TabSheet:TTabSheet;
begin
TabSheet:=PageCtrl.Pages.Create(nil);
TabSheet.Caption:='TestTabSheet';
end;

exports
GetPlugin;


2dm9
Цитата
TabSheet.PageControl := PageControl1;

Лично я не понял, что ты этим хотел сказать confused.gif

Это сообщение отредактировал(а) &-ray - 28.6.2003, 22:31


--------------------
"Совсем неважно от чего помрешь, ведь куда важнее - для чего родился..." С.Б.

--------------------
И снова мышь беру я в руки
Куда иду? - Конечно в сруки!
PM MAIL WWW   Вверх
Fantasist
Дата 30.6.2003, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: нет
Всего: 41



Цитата
Result:=TTabSheet.Create(nil)
и
with Result.Create(nil) do

это одно и то же 


Естесственно, это совсем НЕ одно и то же. Например, равносильны ли следующие строчки кода:

Код

var
 b:TButton;
begin
   b:=TButton.Create(nil);
end;


и

Код

var
  b:TButton;
begin
    b.Create(nil);
end;



Цитата
TabSheet := Proc; - работает
TabSheet.PageControl := PageControl1; - возникает ошибка (cannot assign TFont to TFont)


Бросте эту ерунду. Дело в том, что для с классами, которые возвращает dll не работает RTTI. То есть, так как дллка компилируется отдельно от ехе-шника, то в каждом из них создается своя таблица с информацией о классах. Эти таблицы сравниваются примитивно, по равности указателя на них. Так что даже если эти таблицы абсолютно идентичны, то они будут считаться как принадлежащие разным классам. VCL довольно плотно использует RTTI, например в процедуре Assign:

Код

procedure TFont.Assign(Source: TPersistent);
begin
 if Source is TFont then
    .....
end;


Так как процедура Assign скомпилированна в ехе, а Source в dll, то эта проверка обламывает присвоение на корню. Так что передавать туда-сюда ссылки (dll->exe и наоборот) на VCL-вские компоненты и пытаться их использовать гиблое дело.

Плагины лучше писать при помощи пакетов.


--------------------
Волны гасят ветер...
PM MAIL   Вверх
Vyacheslav
Дата 8.7.2003, 08:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: нет
Всего: 59



Цитата(Fantasist @ 30.6.2003, 17:18)

  Бросте эту ерунду. Дело в том, что для с классами, которые возвращает dll не работает RTTI. То есть, так как дллка компилируется отдельно от ехе-шника, то в каждом из них создается своя таблица с информацией о классах. Эти таблицы сравниваются примитивно, по равности указателя на них. Так что даже если эти таблицы абсолютно идентичны, то они будут считаться как принадлежащие разным классам. VCL довольно плотно использует RTTI, например в процедуре Assign:

Код

procedure TFont.Assign(Source: TPersistent);
begin
 if Source is TFont then
    .....
end;


  Так как процедура Assign скомпилированна в ехе, а Source в dll, то эта проверка обламывает присвоение на корню. Так что передавать туда-сюда ссылки (dll->exe и наоборот) на VCL-вские компоненты и пытаться их использовать гиблое дело.

 

Эти вопросы легко снимаются, если для основного приложения и плагинов включить опцию "Build with runtime package". Во всяком случае это справедливо для Builder'а. В этом случае виртуальные таблицы классов (или как там они в Delphi называются) будут присутствовать для одинаковых классов в одном экземпляре


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Fantasist
Дата 8.7.2003, 23:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: нет
Всего: 41



Цитата
Эти вопросы легко снимаются, если для основного приложения и плагинов включить опцию "Build with runtime package".


Да, я помниться, рекомендовал то же самое, однако, коли плагин пишиться для Delphi/Builder, то и оформить его логично в виде package'а, а не dll.


--------------------
Волны гасят ветер...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0558 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.