| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Visual C++/MFC/WTL > "Разнос" проекта по dll |
| Автор: Coocky 3.11.2005, 11:54 |
| Вообщем зхадача не из легких. Есть SDI где-то с 20 представлениями. К каждому классу представления подключены еще отдельные заголовки других классов, для кнопочек, баз данных, и прочеих женских прелестей. Мне нужно ВЕСЬ проект разбить на либы-каждое представление - либа. 1.Как по умному перенести готовые классы представлений. 2.Как быть с подключенными файлами других классов У меня уже начинает болеть голова.. |
| Автор: nikf 3.11.2005, 15:25 |
| Если конечно есть веские причины тогда конечно можно разнести. берешь бумажку и рисуешь все классы проги и смотришь как они взаимодействуют друг с другом. А потом пытаешься делить.. Какие-то общие классы выделяешь в отдельную dll и потом подключаешь ее к exe и всем dll-кам представлений.. примерно так. |
| Автор: Coocky 3.11.2005, 15:51 | ||
Вот у меня есть общие классы, которые подключаются к окнам. Я их выношу в отдельную dll. Что дальше? нужно подгружать их вв dll ,в которой они используются? Т.е. получается паровоз? А что делать в ехе? Будет ли видеть прога функции dll. которые присоединяются к другой dll? Или надо все подключать в ехе? |
| Автор: Earnest 3.11.2005, 18:48 | ||||
Просто dependences установи. Ты не сказал, но я надеюсь, все это можно оставить в одном воркспэйсе (солюшене).
Подключать нужно только то, что прямо вызывается. Можно не ломать голову, начав с "нулевого" варианта - ничего не подключать, только обеспечить видимость нужных хедеров. Потом, по мере воплей линкера, устанавливать зависимости. Поверь, это вовсе не так страшно. В ехе можно оставить конфигурационный код - где-то же нужно управлять подключением компонент. |
| Автор: nikf 3.11.2005, 19:26 | ||
ты же используешь неявное подключение dll(я так думаю |
| Автор: bel_nikita 3.11.2005, 21:14 | ||||||
На самом деле разбить все на ДЛЛ это очень хорошо. Все идет паровозом А что за SDI? Если это однотипные диалоги, то продумать интерфейс вызова этих ДЛЛ. К примеру, у меня есть "проект пустышка", его задача держать связь с сервером и запускать нужные ДЛЛ по запросу пользователя. Продумал интерфес, который должны соблюдать все длл и последовательность вызова. Все... Теперь несколько человек пишут свои независимые ДЛЛ, а я лишь в xml файле создаю ассоциации: событие - ДЛЛ, т.е. по такому-то событию должна вызываться такая-то ДЛЛ. У меня типа такого интерфейса:
pBufer - это структура для инициализации ДЛЛ, или данные с которыми должна работать данная длл. А вот, такой меню файл (xml), где прописываю очередной пункт меню, ДЛЛ и путь к ней:
Так же можно указывать свои иницилизационные параметры, для каждой отдельной ДЛЛ. Добавлено @ 21:21 А для "разноса" проекта по ДЛЛ рекомендую применить передовую технологию copy-past |
| Автор: Coocky 3.11.2005, 21:44 | ||||||||||
Earnest
Я понял, что ничего незнаю об МФС ДЛЛ Добавлено @ 21:45 bel_nikita
Старина, я не так крут |
| Автор: bel_nikita 3.11.2005, 22:28 |
| Coocky http://www.codenet.ru/progr/visualc/Using-DLL.php http://www.citforum.ru/book/cook/dll1.shtml http://vingrad.ru/CPP-FAQ-001916 |
| Автор: Coocky 4.11.2005, 12:10 |
| Создал свой класс в длл,производный от диалога class My_Dll. Добавил функцию void My_Dll::Create_Dialog (); внутри нее вызвал Create(IDD_DIALOG1); Подключил все к проге, а она не видит Mydll.Create_Dialog (); А вот Mydll.Create(IDD_DIALOG) видит(правда не видит IDD_DIALOG1, ну это и понятно). Если кому не трудно, напишите простенький пример, как экспортировать класс. Что б я понял, как правильно. Чуйка у меня, что не правильно в заголовочном файле длл директивы препроцессора прописую.. |
| Автор: bel_nikita 4.11.2005, 12:20 |
| Coocky а не смотрел ссылки? там как раз есть про экспорт MFC классов Добавлено @ 12:21 могу примерчик проекта сделать, но только вечером |
| Автор: Coocky 4.11.2005, 13:54 |
| bel_nikita Очень прошу! Сделай MFC extension Dll проект, добавь любой диалог. и добавь функцию к классу диалога(к примеру void Coocky_stuped() ) И посмотри-отобразится ли в твоем примере ехе вызов этой функции |
| Автор: bel_nikita 4.11.2005, 21:05 | ||||||||||||||
| Компилятор и IDE: MSVC6 + SP6 1. Создаем стандартный MFC проект MainAppl. 2. Добавляем итем в меню и создаем событие:
4. В опциях проекта прописывам _AFXEXT и выставляем Debug Multithreaded DLL ( по другому: /MDd /D "_AFXEXT" ) 5. Делаем ребилд. Теперь займемся нашей DLL: 6. Создаем в той же директории, что и MainAppl, MFC extensions DLL. У нас это проект CoockyDLL. 7. Создаем в ресурсах диалог и его класс. У нас это CDialogCoocky : public CDialog. 8. Создаем классовую функцию Coocky_Is_You_Function:
9. Вставляем макрос AFX_EXT_CLASS:
10. Комментируем: //enum { IDD = IDD_DIALOG1 };
11. Открываем DialogCoocky.cpp и прописываем: IDD_DIALOG1
12. В файле StdAfx.h прописываем: #include "resource.h" 13. Делаем ребилд. Наша DLL готова. Возвращаемся к нашему MainAppl. 14. Подключаем к проекту файл DialogCoocky.h 15. В файле StdAfx.h прописываем: #include "CoockyDLL/DialogCoocky.h" 16. В файле StdAfx.cpp прописываем:
17. Теперь возвратимся к нашей функции OnCoockyDll(), в которой вызываем диалог из DLL:
18. Делаем ребилд проекта. 19. Копируем нашу CoockyDLL.dll в %PROJECT\Debug\ 20. Нажимаем Execute MainAppl.exe и наслаждаемся З.Ы.: проблемы типа: а чего в моей длл вызываются ресурсы ехе проекта - не рассматривались и мною опущены |
| Автор: bel_nikita 4.11.2005, 21:05 |
| Ехе архив |
| Автор: Coocky 7.11.2005, 12:48 | ||||
Итак анализируем. Этому меня неучили да и в мануалах ненашел! Может из-зи этого трабла у меня была. Сейчас гляну Добавлено @ 12:50
Этого у меня нет..Но это наверное код "шестерки" |
| Автор: bel_nikita 7.11.2005, 12:56 | ||
Coocky
|
| Автор: Coocky 7.11.2005, 15:30 | ||
Стоп,стоп стоп.. Дык при выбре MFC extension dll блокируется галочка Automation Ты какой тип проекта создавал? |
| Автор: bel_nikita 7.11.2005, 15:48 | ||
MFC extension создавал |
| Автор: Coocky 7.11.2005, 16:01 | ||
Ну раз ТОЧНО, тогда я спокоен.. |
| Автор: bel_nikita 7.11.2005, 16:07 |
| Coocky Еще раз попробывал. У меня ничего не блокируется. Могу бырать Automation и Win Sockets. Проект MFC Extension DLL. Все это пробывалось на MSVC6 SP6. |
| Автор: Earnest 8.11.2005, 18:07 | ||||||
| Coocky 1) Dependencies - это команда Project->Dependencies, и там галки ставишь, что от чего зависит. 2) 20 и более проектов среда тянет легко. 3) Чтобы что-то экспортировать, нужно в объявлении функции или класса в источнике (DLL) написать __declspec(dllexport), а в клиенте (EXE) - __declspec(dllimport). Так как обычно объявления пишут в хедерах, и не хочется их дублировать для DLL и EXE, обычно делают что-то вроде (см. MFC):
При этом символ _AFXEXT у тебя определен в DLL (т.е. там ты имеешь экспорт). А в EXE - cоответственно, импорт. Только для этого символ _AFXEXT и нужен. НО: если есть некая общая DLL, функциями/классами которой пользуются другие (т.е. есть зависимость между библиотеками), такой фокус не пройдет. У обеих библиотек символ _AFXEXT определен - получается, все экспортируется - и свое, и чужое. Тогда для каждой DLL нужно завести свой символ, и написать подобные объявления. Скажем, есть DLL MegaSuperDLL. Для нее определяем символ _MEGASUPER (в параметрах препроцессора). Далее, создаем хедер MegaSuper.h:
Далее, пишем класс, который будет экспортироваться:
В этом случае экспортируются все функции класса, а если надо экспортировать выборочно, то MEGASUPER_API пишем не у класса, а у определений этих функций. Вот и все. |
| Автор: Coocky 8.11.2005, 18:25 | ||||
| Earnest Совсем запутали... Смотри, что у bel_nikita Файл Dll.h (библиотеки)
Dll.cpp стандартный, как у ЕХЕ. В опциях проекта Dll добавлено в С++-> Preprocessor ->Preprocessor Definition _AFXEXT ВСЕ! В ЕХЕ просто продублирован класс, как в длл, и также настроен препроцессор. Просто класс я ля копи-пасте.. Так что же делать? Кто прав? Как правильно? Вообще у меня не работало, из-за неправильного описания препроцессора. Но кто из вас прав? Хотя похожи методы, но вроде попроще у bel_nikita Добавлено @ 18:26
Дружище, давно пора переходить на новые компиляторы.. В семерке запрещает.. |
| Автор: Coocky 8.11.2005, 18:48 |
| Вопросы в догонку... Можно ли установить неявно подключаемую длл не каталоге исполняемого модуля. Если да , то как( а то длл много, хочу по папкам раскидать..) То что lib прописывается -это одно, а вот длл -то ищется в каталоге exe... Добавлено @ 18:53 Как правильно пользоваться AfxGetResourceHandle(); AfxSetResourceHandle(); для использования ресурсов длл, а не проекта.. |
| Автор: Earnest 8.11.2005, 19:07 | ||
| Coocky У нас почти одно и то же. Я просто тебе в чем суть попыталась объяснить. 1) Посмотри что такое AFX_EXT_CLASS - это ровно __declspec(dllexport) или __declspec(dllimport), в зависимости от наличия _AFXEXT. 2) Дублировать объявления классов нехорошо! А поддержка?!!! Это же застрелиться можно - в нескольких местах синхронно править!! Лучше использовать один и тот же хедер. Символ типа AFX_EXT_CLASS для того и нужен, чтобы по разному интерпретироваться в зависимости от модуля, в котором это компилируется. 3)
Все - это если у тебя нет зависимости между разными extension DLL. А если есть - простой метод не пройдет - нужны разные символы, для каждой DLL свой. А так - суть та же. |