Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Многопроектное решение - как собрать в единый exe? 
:(
    Опции темы
suvolod
Дата 19.2.2011, 21:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Я пишу приложение с использованием mfc (на основе диалога со статически прилинкованной библиотекой mfc). Мое приложение условно можно разделить на две форточки - основное окно программы и окно настроек этой программы.  И основное, и окно настроек содержит кучу классов. Например, окно настроек состоит из пяти вкладок  (соответственно, на каждую вкладку есть класс + еще парочка на основное окно), в основном приложении классов еще больше. Сейчас в моей проге все классы свалены в одну кучу: и основная программа, и окно ее настроек представляют единый проект. Ориентироваться очень трудно... поэтому я хочу создать солюшен, в котором будут два проекта - для программы и для окна ее настроек. Трудность в том, что я хочу затем собрать этот солюшен в единый exe-файл. Бьюсь уже неделю, но пока ничего не получается. 

1. Сперва я хотел сделать оба проекта exe-шниками, затем проект окна настроек преобразовать в lib (через настройки проекта VStudio) и радоваться жизни. Не получилось. преобразование exe-в lib проходит успешно. Либа подключется к основному проекту и все выполняется без ошибок, но вызов окна настроек по Dlg.DoModal() возвращает -1 (Dlg - это объект класса диалогового окна настроек, лежащего в lib-е). 
2. Затем я попробовал сделать то-же самое, но уже не преобразуя готовый exe-проект, а создать dll-проект, создать в нем ресурс типа диалоговое окно, создать класс этого диалогового окна, а затем уже преобразовать его в lib-у. Я предполагал, что lib-библиотека по своему строю гораздо ближе к dll библиотеке, а значит у меня все получиться. В итоге у меня получилось создать солюшен из двух проектов (exe и dll), запихнуть в dll диалог и вызвать его из exe-шника. Но дальше дело не пошло. После превращения dll-проекта в lib сразу же полезли ошибки вроде:
Код

error LNK2019: unresolved external symbol "__declspec(dllimport) void __cdecl Show(void)" (__imp_?Show@@YAXXZ) referenced in function "public: void __thiscall CEXEDlg::OnBnClickedButton1(void)" (?OnBnClickedButton1@CEXEDlg@@QAEXXZ)

... оно и правильно, ведь lib-библиотека не имеет собственного хендла и ничего не знает про __declspec(dllimport) / __declspec(dllexport) разделяемой dll. А удаление этих импорт/экспорт-определений вернуло меня назад: либа собирается, но из exe-проекта окно вызвать невозможно, Dlg.DoModal() возвращает (-1). 
3. А теперь вопрос? Кто-нибудь с этим сталкивался? Все-таки можно собрать солюшен из нескольких проектов в единый exe-файл? Или, перефразируя, как вызвать диалог из lib-библиотеки? Ссылку на статью, примерчик, просто подсказку - буду рад любой помощи. На всякий случай выкладываю свой пример (exe+dll в одном солюшене), может кто-то сможет преобразовать его в солюшен аля (exe+lib). 


Это сообщение отредактировал(а) suvolod - 19.2.2011, 21:36
PM MAIL   Вверх
Earnest
Дата 20.2.2011, 08:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



"Как вызвать диалог из lib ?" 
Никак: статическая библиотека не может содержать ресурсов. Разве что создавать диалог в ней динамически. Но ради такого счастья не стоит делить проект на модули.
Ресурсы может содержать DLL. Динамическая библиотека как раз по своему устройству гораздо ближе к exe, чем к lib. Это тоже исполняемый модуль. Но собрать его с основным проектом в один exe никак не получится: придется поставлять 2 отдельных модуля - exe и dll.
Твое решение - выделить окно настроек в отдельную библиотеку - не кажется обоснованным. Было бы ради чего. Много классов? У меня в модулях по несколько сотен классов, и ничего. Сделай в проекте папки по темам и радуйся жизни.

Далее, если таки использовать DLL, нужно выполнить ряд условий: во первых никаких статических mfc и прочих crt. Во-вторых, нужно знать, что (с точки зрения mfc) DLL бывают Regular и Extension. С точки зрения АПИ это, конечно, одна фигня, но mfc-фрейворк наворачивает разные штучки для экспорта. Для начала неплохо бы вообще разобраться в экспорте-импорте символов из DLL. Для этого читать MSDN - там все подробно описано. После этого переходить к описанию DLL именно c точки зрения MFC, тоже все подробно описано.


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


Шустрый
*


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

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



Кстати, читал уже (в другой теме) твое утверждение, что lib-а не может содержать ресурсов, но почему тогда студия 2005 мне это позволяет? Создают проект: File->New->Proect->Win32 Proect ->Static Library. Затем на вкладке Resource View: клик правой кнопкой ->Add->Resource->Dialog. Далее все как обычно - создаю класс диалога, компилирую ... все проходит без ошибок и на выходе у меня lib-а. 

А вот насчет "Сделай в проекте папки по темам и радуйся жизни" - это очень интересно... Но как это сделать? В окне ClassView невозможно создать ползовательскую папку и раскидать классы по этим папкам. Как понял я, единственный путь превращения линейного списка классов в окне ClassView в упорядоченное дерево - это либо выделить/раскидать классы по отдельным проектам, либо на каждую группу классов выделить свое пространство имен. С первым способом я зашел в тупик; сегодня буду пробовать второй, хотя мне он очень не нравиться... засорять свой код бесконечными квалификациями используемого пространства либо отслеживать/пихать в заголовки using-директивы ... для моего проекта это зло... 

Это сообщение отредактировал(а) suvolod - 20.2.2011, 10:23
PM MAIL   Вверх
suvolod
Дата 20.2.2011, 10:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Сам спросил, сам себе отвечаю. Оказывается, в студии существует возможность раскидать классы по пользовательским папкам. Долго и упорно искал эту фичу в контекстном меню ClassView, а надо было поднять глаза чуть выше, чтобы увидеть значок новой папки smile

Но вопрос насчет насчет хранения ресурсов в lib-е остается открытым. 
PM MAIL   Вверх
Albor
Дата 20.2.2011, 11:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(suvolod @  20.2.2011,  09:34 Найти цитируемый пост)
Сам спросил, сам себе отвечаю. Оказывается, в студии существует возможность раскидать классы по пользовательским папкам. Долго и упорно искал эту фичу в контекстном меню ClassView, а надо было поднять глаза чуть выше, чтобы увидеть значок новой папки . 

Да, этот сервис существовал и в 6й студии, только там это было организовано, с моей точки зрения, немного лучше: класс "перемещался" в нужную папку, а не "копировался" как сейчас. 
PM MAIL ICQ   Вверх
suvolod
Дата 20.2.2011, 13:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



И все-таки у меня получилось.. На исходниках подкинули ссылку на статью Visual C++ и ресурсы в статической библиотеке. Cоздал солюшен на основе mfc-диалога, в него добавил проект Win32 ->Static Library (c галкой mfc), в него добавил диалог, создал класс этого диалога. Отредактировал rc-файл через Resource View->правый клик по rc exe-проекта -> Resource Includes и в появившемся диалоге прописал пути до файлов lib-проекта: 

в верхнем edite - #include "..\\LIB\\resource.h"
в нижнем - #include "..\\LIB\\LIB.rc"

Все заработало, причем, что особенно приятно, можно вызывать диалоговые окна не через промежуточную функцию самой библиотеки (как это делается в случае с dll-проектом), а напрямую, создавая объект диалога и вызывая его по DoModal(). 

Для тех, кто пойдет по моему пути, напомню, что в настройках проекта очень важно выбрать одинаковую версию CRT для exe и lib-проекта (я пользовался Multi-threaded Debug (/MTd)) + одинаковое значение настройки General->Use MFC (у меня стоит Use MFC in a Static Library), иначе вы встретитесь с непонятными ошибками при линковке солюшена. 
Еще пара замечаний: 
1/ Иногда проект почему-то не собирается по кнопке "Buil Solution", но отлично компилируется по отдельности - сначала lib, затем dll. 
2/ В поисках решения периодически натыкался на топики о том, что при вызове диалога из dll часть элементов управления не отображается. Пока с этим не встречался, но на всякий случай сразу выкладывают решение - при появлении такого косяка попробуйте в lib-проекте явно вызвать функцию InitCommonControls для инициализиации стандартных элеменетов и InitCommonControlsEx для инициализации расширенных элементов типа деревья. Ну и выкладываю сам тестовый примерчик аля (exe+lib)


Это сообщение отредактировал(а) suvolod - 20.2.2011, 18:13

Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  EXE2LIB.7z 23,17 Kb
PM MAIL   Вверх
maxim1000
Дата 20.2.2011, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(suvolod @  20.2.2011,  13:56 Найти цитируемый пост)
1/ Иногда проект почему-то не собирается по кнопке "Buil Solution", но отлично компилируется по отдельности - сначала lib, затем dll. 

есть смысл проверить порядок сборки
для того, чтобы нормально собрать exe, нужно, чтобы все lb-проекты были уже собраны
для этого нужно установить dependencies (правой кнопкой на exe-проекте, "Project Dependencies..." и поустанавливать галочки)


--------------------
qqq
PM WWW   Вверх
Earnest
Дата 21.2.2011, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Хм, действительно можно, хотя и чрезвычайно проктологически.
Что студия имеет в виду, позволяя добавить ресурсы к проекту статической библиотеки, сказать трудно. Возможно тот самый проктологический путь - ведь известно, что в основной rc-файл всегда можно включить дополнительные. Непонятно, почему бы ей самой это не сделать в таком случае...
Но тем не менее, остаюсь при своем мнении: все-таки удобство библиотеки в том, что она подключается одним движением и все необходимое в себе содержит. А раз это не получается, то - DLL.


--------------------
...
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




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


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

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