Поиск:

Ответ в темуСоздание новой темы Создание опроса
> КатастроФФа с RegisterClass (EFilerError), A class named ... already exists  
:(
    Опции темы
vaddsm
Дата 20.7.2007, 07:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Ситуация такая есть две dll каждая из которых имеет по форме, обе формы наследницы одного и тогоже класса (условно TОкноПрородитель), так вот после подключения к хост приложению каждая дллька регистрирует класс своей формы путем вызова RegisterClass.


Код

void __fastcall TForm1::localRegisterClass(TMetaClass *M)
{
 AnsiString s = M->ClassName();
 if(GetClass(s) == NULL) RegisterClass(M);
};



Этот код находиться в хост приложении, а длл передается адрес на эту функцию. Так, вот с регистрацией первой формы проблем не возникло, а вот регистрация второй, приводит к ошибке A class named TОкноПрородитель already exists. Я в панике! Чего с этим можно сделать? 

P.S Дллели подключаются в рантайме.
PM MAIL   Вверх
vaddsm
Дата 20.7.2007, 07:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



НАШЕЛ подсказ на свою проблему:

Цитата

Очевидно, что:
а) регистрируется класс и все его предки, до TPersistent включительно;
б) регистрация выкидывает исключение, если уже зарегистрирован класс с таким же именем;
в) функция Registered проверяет наличие класса как указателя в списке, а не по имени.

Поэтому классы (или потомки класса) с одним именем, но физически различные (как TIndicatorDevice в разных DLL), не удается зарегистрировать более одного раза.

Поэтому я и говорю, что нужно обеспечить уникальность модуля с базовыми классами в масштабах приложения, что возможно только при использовании пакетов. 

Только с BPL можно не включать общий модуль в каждую BPL, а вынести в отдельную. С DLL этот фокус не пройдет.

Примечание (если еще не понятно): BPL, содержащая общие юниты, привязывается к проекту EXE и плагинам статически, а сами плагины, очевидно, грузятся динамически кодом, расположенным в EXE или в этой общей BPL (разницы никакой). Можно даже большую часть кода EXE вынести в этот пакет - ядро приложения. Тогда плагинам автоматически будут доступны все программные модули, и они (плагины) смогут сделать с интерфейсом пользователя все, что захотят. А сам экзешник выродится в маленький такой загрузчик.


Цитата

2. Используйте Build with runtime packages и плагины в BPL. Модуль с базовыми классами и все вспомогательные модули общего пользования вынесите в отдельную BPL, которая будет использоваться всеми плагинами и главной программой.


http://www.delphikingdom.ru/asp/answer.asp?IDAnswer=25650


В моем случае 

Класс с одним и тем же именем это:

Код

class TCMSChild : public TForm
{

}


Его то и наследуют две злаполучные формы. Объясните мне пожалуйста как мне его в BPL завернуть и как этот самый BPL куда подключить чтобы решить описанную проблему.




PM MAIL   Вверх
HappyLife
Дата 20.7.2007, 16:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



vaddsm, Зачем тебе регистрировать класс? Он итак регистрируется автоматом, когда создается форма. Либо пиши сам имя класса. И Используй свойство Name

Это сообщение отредактировал(а) HappyLife - 20.7.2007, 16:12
PM MAIL   Вверх
vaddsm
Дата 20.7.2007, 18:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Класс регистрируется, чтобы хост приложение могло сконструировать форму е имея представления из чего она сделана, только зная ее имя. Это реально если предварительно провести регистрацию класса как было сказано выше. а затем вызвать данный код:

Код

lpTForm __fastcall TForm1::CreateMetaForm(char *Name, TComponent *Owner)
{

 TForm * Result = NULL;
 TMetaClass *M = GetClass((AnsiString) Name);

 if(M != NULL)
 {

  typedef DWORD  VMT [vmtCreateObject];
  typedef TComponent * ( __fastcall  * TConstructor )(TComponent *Self, bool B, TComponent *AOwner);


  void *mem = 0;

  TConstructor Create;

  VMT ** V;

  mem = new char[M->InstanceSize()]; // çàêàçûâàåì íàìÿòü

  Result = (TForm*)M->InitInstance(mem); // ñîçäà¸ì êîìïîíåíò

  V = (VMT**) Result;
  Create = (TConstructor) (**V)[vmtCreateObject-1]; // äîñòà¸ì êîíñòðóêòîð

  Create(Result, FALSE, Owner); // âûçûâàåì êîíñòðóêòîð

 }

 return Result;

}



В моем случае два плагина регистрируют разные формы но обе наследующие класс TОкноПрородитель. И когда регистрируется вторая форма, вылетает эксепшин что мол TОкноПрородитель уже зарегистрирован. Это происходит така как RegisterClass регистрирует все дерево классов. Со всеми его предками. ОДНАКО! если убрать из наследования формой TОкноПрородитель и вместо него сделать тривиальную форму наследницу TForm все пройдет на ура! 

Почему черт возьми так происходит! Кто мне может объяснить. Вот тут http://www.delphikingdom.ru/asp/answer.asp?IDAnswer=25650 написано черным по белому что проблему можно решить используя BPL, но как я не могу понять!



PM MAIL   Вверх
vaddsm
Дата 20.7.2007, 20:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



УРА!!!  smile  smile  smile УРА!!! 

Проблема решена! Собственно как и было сказано в упомянутой статье так и надо было сделаь. 
Всем столкнувшимся с подобной проблемой посвещаятся:

Создайте компонент с проблемным классом. Затем подключите bpl к хост-приложению и ко всем плагинам (dll) статически.  В области видимости тех мест где ваш компонент используется подключите инклудом хедр с описанием его класса. Откомпилируйте заново плагины и хост приложение. Воля!



PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

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

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

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

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


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

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


 




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


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

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