Фабрика класса
От: AcidTheProgrammer Россия https://hts.tv/
Дата: 13.02.13 07:26
Оценка:
Все доброго времени суток.
Возникла неразрешимая для меня проблема с фабрикой класса при переносе кода в статическую библиотеку.
Был набор классов которые автоматически регистрировали себя в статических конструкторах в неком списке. В exe и dll все работало. При переносе кода в библиотеку (.lib) линкер стал выкидывать классы т.к. по всей видимости он не видит внешних ссылок на классы. Как решить данную проблему без добавления явных ссылок для каждого класса (иначе теряется весь смысл)? Может быть кто-нибудь решал подобную задачу. Поиск по форумам в интернете ничего не дал.
Re: Фабрика класса
От: rg45 СССР  
Дата: 13.02.13 07:52
Оценка:
Здравствуйте, AcidTheProgrammer, Вы писали:

ATP>Все доброго времени суток.

ATP>Возникла неразрешимая для меня проблема с фабрикой класса при переносе кода в статическую библиотеку.
ATP>Был набор классов которые автоматически регистрировали себя в статических конструкторах в неком списке. В exe и dll все работало. При переносе кода в библиотеку (.lib) линкер стал выкидывать классы т.к. по всей видимости он не видит внешних ссылок на классы. Как решить данную проблему без добавления явных ссылок для каждого класса (иначе теряется весь смысл)? Может быть кто-нибудь решал подобную задачу. Поиск по форумам в интернете ничего не дал.

Для этого есть старый испытанный трюк. Нужно определить вспомогательный класс, не содержащий ничего, кроме дефолтнгого конструктора. В каком-то из общих заголовков определить глобальную константу этого класса. И, самое главное, определение дефолтного конструктора (оно будет пустым) нужно выполнить в том cpp-файле, для которого необходимо обеспечить линковку.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re: Фабрика класса
От: uzhas Ниоткуда  
Дата: 13.02.13 08:10
Оценка:
Здравствуйте, AcidTheProgrammer, Вы писали:

ATP>Был набор классов которые автоматически регистрировали себя в статических конструкторах в неком списке. В exe и dll все работало. При переносе кода в библиотеку (.lib) линкер стал выкидывать классы т.к. по всей видимости он не видит внешних ссылок на классы. Как решить данную проблему без добавления явных ссылок для каждого класса (иначе теряется весь смысл)? Может быть кто-нибудь решал подобную задачу. Поиск по форумам в интернете ничего не дал.


еще один трюк: для линкера (при настройках по умолчанию для gcc или VS) .obj является неделимой сущностью: в финальный бинарь попадает либо .obj полностью, либо никакая часть .obj не попадает.
.lib является набором из нескольких .obj.
так вот, если зацепить хоть маленькую часть .obj, то он залетит в финальный бинарь полностью
как этим воспользоваться:
пусть у нас есть a.cpp в котором создается объект, который себя где-то регистрирует
A globalVar;//it registers itself in some repository in constructor


можно сюда добавить пустую функцию и вызвать ее из того .cpp, который точно попадает в финальный бинарь. таким образом он потянет за собой a.obj независимо от того в статической либе он или отдельный .obj файл

A globaVar;

void DummyFunction()
{
//empty body
}


main.cpp:
int main()
{
  DummyFunction(); // here we are sure globalVar will be created and a.cpp will be linked with resulting .exe
}


в то же время есть настройка для линкера для оптимизации линковки, которая заставляет линкер крошить .obj на более маленькие части. в этом случае наш трюк перестанет работать. этот вид оптимизации очень тормозной, поэтому его редко используют
успехов
Re: Фабрика класса
От: AcidTheProgrammer Россия https://hts.tv/
Дата: 13.02.13 08:20
Оценка:
Здравствуйте, rg45 и uzhas:

Я понимаю причину, все что вы предлагаете верно и сработает, но такие "зацепки" ссылок мне нужно будет проделать для каждого cpp, для каждого класса. До библиотеки все что нужно было это отнаследовать класс от некого базового и поместить его cpp в проект и все. Классов много, порядка 50, и делать такие хаки для каждого, будет равносильно ручному их перечислению их конструкторов в одной из функций. Это дискредитирует всю идею автоматической регистрации класса в фабрике.
Re: Фабрика класса
От: Erop Россия  
Дата: 13.02.13 08:33
Оценка:
Здравствуйте, AcidTheProgrammer, Вы писали:

ATP>Был набор классов которые автоматически регистрировали себя в статических конструкторах в неком списке. В exe и dll все работало. При переносе кода в библиотеку (.lib) линкер стал выкидывать классы т.к. по всей видимости он не видит внешних ссылок на классы. Как решить данную проблему без добавления явных ссылок для каждого класса (иначе теряется весь смысл)? Может быть кто-нибудь решал подобную задачу. Поиск по форумам в интернете ничего не дал.


Какие компиляторы ты хочешь поддержать?

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

Но есть и более прямой путь, конечно.

Хот на мой вкус это из пушки по воробьям.

Смотри, можно сделать так, что бы между твоей нынешней базой и реальным наследником была ещё шаблонная прокладка. Она должна параметризовываться типом реального класса-наследника (см. CRTP)
Вот, регистрацию делаешь в статическом поле этой CRTP-прокладки, только не забуь дать определение шаблона самого статического поля...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Фабрика класса
От: uzhas Ниоткуда  
Дата: 13.02.13 08:35
Оценка:
Здравствуйте, AcidTheProgrammer, Вы писали:

ATP>Это дискредитирует всю идею автоматической регистрации класса в фабрике.

согласен, лично для себя я решил не использовать подобные автоматические регистрации
здесь мы сталкиваемся со многими проблемами, описанными во многих книжках, которые свойственны глобальным переменным и синглтонам:
проблемы с реюзом, проблемы синхронизации, проблемы юнит-тестирования, проблемы с зависимостями и другие
у подобных решений есть и очевидные плюсы: удобство\простота расширения, меньше букв\усилий, какие-то вещи делаются автоматически, не надо о них думать и тд.
не хочу холиворить, но для себя я решил, что _явная_ регистрация лучше автоматической, глобальные переменные лучше избегать — класс, ответственный за создание лучше передать в функцию _явно_, нежели надеятся, что функция найдет некий глобальный объект для этого.
успехов
Re[2]: Фабрика класса
От: AcidTheProgrammer Россия https://hts.tv/
Дата: 13.02.13 08:39
Оценка:
Здравствуйте, Erop, Вы писали:

E>Какие компиляторы ты хочешь поддержать?

Интересует VC 9.0

E>В обоих двух популярных, можно помечать класс, как экспортируемый, и его тогда возьмут и без ссылок

Можно примерчик

E>Но есть и более прямой путь, конечно.

E>Хот на мой вкус это из пушки по воробьям.

E>Смотри, можно сделать так, что бы между твоей нынешней базой и реальным наследником была ещё шаблонная прокладка. Она должна параметризовываться типом реального класса-наследника (см. CRTP)

E>Вот, регистрацию делаешь в статическом поле этой CRTP-прокладки, только не забуь дать определение шаблона самого статического поля...

Сейчас так и сделано, класс нужно унаследовать от шаблона, который уже сам создает статический объект и все что нужно регистрирует. Т.е. полная автоматизация, никакие переменные руками создавать не нужно. За это и борюсь.
Re[3]: Фабрика класса
От: AcidTheProgrammer Россия https://hts.tv/
Дата: 13.02.13 08:41
Оценка:
Здравствуйте, uzhas, Вы писали:

U>согласен, лично для себя я решил не использовать подобные автоматические регистрации

U>здесь мы сталкиваемся со многими проблемами, описанными во многих книжках, которые свойственны глобальным переменным и синглтонам:
U>проблемы с реюзом, проблемы синхронизации, проблемы юнит-тестирования, проблемы с зависимостями и другие
U>у подобных решений есть и очевидные плюсы: удобство\простота расширения, меньше букв\усилий, какие-то вещи делаются автоматически, не надо о них думать и тд.
U>не хочу холиворить, но для себя я решил, что _явная_ регистрация лучше автоматической, глобальные переменные лучше избегать — класс, ответственный за создание лучше передать в функцию _явно_, нежели надеятся, что функция найдет некий глобальный объект для этого.
U>успехов

Полностью согласен. Как на зло все эти фабрике всегда были в exe или dll и вот неожиданно накололся с либой. Если ничего сделать будет нельзя, то ваша точка зрения полностью станет и моей
Re[3]: Фабрика класса
От: Erop Россия  
Дата: 13.02.13 10:20
Оценка:
Здравствуйте, AcidTheProgrammer, Вы писали:

ATP>Интересует VC 9.0


ATP>Сейчас так и сделано, класс нужно унаследовать от шаблона, который уже сам создает статический объект и все что нужно регистрирует. Т.е. полная автоматизация, никакие переменные руками создавать не нужно. За это и борюсь.


Ну так скажи про этот статический объект __declspec( dllexport ) и само взлетит по идее...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Фабрика класса
От: AcidTheProgrammer Россия https://hts.tv/
Дата: 13.02.13 10:41
Оценка:
Здравствуйте, Erop, Вы писали:

E>Ну так скажи про этот статический объект __declspec( dllexport ) и само взлетит по идее...


А что в статической либе данные спецификаторы тоже пашут?
Re[5]: Фабрика класса
От: rg45 СССР  
Дата: 13.02.13 10:48
Оценка: 2 (1)
Здравствуйте, AcidTheProgrammer, Вы писали:

ATP>Здравствуйте, Erop, Вы писали:


E>>Ну так скажи про этот статический объект __declspec( dllexport ) и само взлетит по идее...


ATP>А что в статической либе данные спецификаторы тоже пашут?


Они пашут не в статической либе, а в исполняемом модуле (dll или exe), который линкует эту либу.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[5]: Фабрика класса
От: Erop Россия  
Дата: 13.02.13 10:55
Оценка:
Здравствуйте, AcidTheProgrammer, Вы писали:

ATP>А что в статической либе данные спецификаторы тоже пашут?


У VC9 статическая либа -- это просто коллекция объектников...
Эти объекты будут экспортироваться из того exe или dll, которые прилинкуют либу и, тааким образом, будут взяты...

Другое дело, что это неудобно для пользователя статической либы. Обычно оттуда берут тока нужное...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: Фабрика класса
От: AcidTheProgrammer Россия https://hts.tv/
Дата: 13.02.13 11:00
Оценка:
Здравствуйте, rg45, Вы писали:

R>Они пашут не в статической либе, а в исполняемом модуле (dll или exe), который линкует эту либу.


Все, спасибо понял идею, нужно только попробовать.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.