![]() |
|
|
![]()
|
|
| takedo |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 501 Регистрация: 1.6.2005 Репутация: нет Всего: 3 |
Создал визардом VS2005 проект Dll, а функция DllMain не сгенерировалась. Раньше, в VS6 функция автоматом прописывалась. Попробовал добавить вручную, куча ошибок компилятора выскочила. В поиске нашел темку похожую, но там только сказали, что тема знакомая - куча макросов МФЦ, содержащих обращение к DllMain, но ничего никто не объяснил. Может кто сможет толком объяснить как прописать DllMain без проблем?
PS.: Фукнция мне реально нужна, заглушка не устраивает -------------------- я не гольфист - я хоккеист |
|||
|
||||
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: нет Всего: 121 |
-------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
| takedo |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 501 Регистрация: 1.6.2005 Репутация: нет Всего: 3 |
вопрос лишь в том в какой файл это вставить. Я вставил функцию в единственный сгенерированных файл, но посыпались ошибки. Отличие было в том, что я не прописывал windows.h Ладно, надо идти пробовать...
-------------------- я не гольфист - я хоккеист |
|||
|
||||
| W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: нет Всего: 121 |
Не знаю, может людям имеющим дело в MFC будет понятно и так, но без лога компиляции у меня никаких мыслей дальнейших не возникает.
-------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 87 Всего: 183 |
takedo, ту какой проект генерировал? Может MFC, но не Extension DLL? Тогда и не должно появиться DLLMain. Т.е. она, конечно, есть, но не в твоем коде...
Ты бы просто собрал полученный проект, может он нормально собирается... -------------------- ... |
|||
|
||||
| takedo |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 501 Регистрация: 1.6.2005 Репутация: нет Всего: 3 |
Вставляю функцию и получаю:
1>Linking... 1>uafxcwd.lib(dllmodul.obj) : error LNK2005: _DllMain@12 already defined in subd01.obj 1> Creating library d:\programs\bases1\subd01\Debug\subd01.lib and object d:\programs\bases1\subd01\Debug\subd01.exp 1>d:v\programs\bases1\subd01\Debug\subd01.dll : fatal error LNK1169: one or more multiply defined symbols found Проект не extension dll. Вот и как от этого избавляться не знаю -------------------- я не гольфист - я хоккеист |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 87 Всего: 183 |
Без ручной доводки напильником собирается?
Вариантов я вижу 2: 1) сделать проект заново, MFC Extension DLL. Тогда возделенная DLLMain будет. 2) понять, действительно ли тебе так нужна DllMain. Если у тебя проект MFC Regular DLL, то у тебя в основном файле должен быть объект-наследник CWinApp, у которого есть виртуальные функции InitInstance и ExitInstance. Которые, в свою очередь, вызываются из внутренней DllMain в начале и конце. Читай Tech Note 11. Но, имей в виду, при использовании Regular DLL есть некоторые тонкости с ресурсами... Обычно Extension DLL в связке с MFC пользоваться удобнее. -------------------- ... |
|||
|
||||
| takedo |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 501 Регистрация: 1.6.2005 Репутация: нет Всего: 3 |
такс, объект-наследник CWinApp есть. Попробую создать Extension DLL, но такие dll кажется не могут внедрить в себя все необходимые функции из mfc, то есть прийдется таскать с собой mfcшные dll. Или я осень ошибаюсь?
-------------------- я не гольфист - я хоккеист |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 87 Всего: 183 |
Нет, не ошибаешься. Правда, я не уверена, что Regular DLL в этом не нуждается, но вероятность такая есть... Почитай tecnical Note. Если тебе нужна отдельная DLL, которая подключается к чему угодно (а не обязательно к MFC-приложению), то это, конечно, Regular. Ну так и делай то, что тебе надо на InitInstance и ExitInstance, в чем проблема-то? Почему обязательно нужна DllMain?
-------------------- ... |
|||
|
||||
| takedo |
|
||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 501 Регистрация: 1.6.2005 Репутация: нет Всего: 3 |
Нашёл интересный материал по адресу andy.uvarov.ru. Есть там книга по VisualC++ для начинающих. Там есть глава 12 - про Dll. И есть там непонятные мне абзацы:
или вот ещё:
То есть не могу понять толком, что же значит обмен Dll с приложением указателем на классы, производные от MFC?? Свою задачку я сделал через обычную статическую Regular Dll и мне в принципе все понравилось и устроило. В Dll есть несколько классов и пара функций, которые я экспортирую и применяю в приложении. Но не все гладко, есть ругательства компилятора при сборке Dll, они правда warning, но очень хочется знать чего это? :
класс выглядит примерно так:
ну и там дальше ещё куча функций. Так вот на каждый класс MFC вылазит однотипное (см. выше) сообщение компилятора. Таким образом, если кто знает прошу Вас обяснить: 1) когда же все таки надо использовать Regular Dll, а когда есть смысл Extension? 2) Что за ошибки выдает компилятор? -------------------- я не гольфист - я хоккеист |
||||||||
|
|||||||||
| Earnest |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 87 Всего: 183 |
Нет, в твоем источнике написано не совсем удачно. Речь идет только о тех объектах, которые известны MFC-оболочке: фреймы, вью, документы и прочая. И то, при некоторой доводке напильником все возможно. Эту фразу следует понимать примерно так: если у тебя Extension DLL, то все происходит точно так же, как если бы ты писал код в одном модуле. А с Regular DLL это не так. Дело в том, что каждый MFC-модуль (т.е. объект, производный от CWinApp или CWinThread - точно не помню, кто именно) - таскает с собой списки созданных окон и еще кучу всего. Проблемы с Regular DLL возможны следующие: создал ты окно в главном модуле, а в DLL хочешь к нему как-то обратиться. Если ты передашь указатель на CWnd*, то большинство функций будет работать нормально (кроме разрушения). Но есть функции, которые проверяют, соответствует ли хандл окна указателю на объект (и проверяют это через список своего модуля). Вот с ними будут проблемы. Опять же, если у тебя есть хандл, и ты хочешь получить указатель на объект через CWnd::FromHandle, то в другом моделе ты получишь шиш с маслом (или временный объект, а вовсе не тот, на который расчитываешь). С собственными классами, производными от CObject, можешь делать что хочешь, если не используешь их COM-возможности. Будут ли работать последние - я не знаю, не использовала. Классы, не производные от CObject - вообще все твое. Нужно только иметь в виду тонкости с разрушением динамических объектов: если модули используют разные экземпляры ран-тайма, то разрушение объекта должно происходить там же (в том же модуле), что и создание. Но лучеш, конечно, чтобы все пользовались общей копией динамической ран-тайм DLL. Насчет предупреждений компилятора: Видимо, при подсоединении к Regular DLL CCriticalSection и прочие не экспортируются. Строго говоря, Regular DLL использует MFC только для собственных нужд, а не ре-экспортирует ее интерфейсы, как это происходит в Extension. Проще всего от этого избавиться, экспортировав не весь класс целиком, а только необходимые функции. Т.е. так:
Это, кстати, даст дополнительную гарантию насчет корректного создания\разрушения, т.к. конструктор и деструктор ты не экспортируешь. И лучше сделать это явно, т.е. написать конструктор и деструктор, даже если они пустые. -------------------- ... |
||||
|
|||||
| takedo |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 501 Регистрация: 1.6.2005 Репутация: нет Всего: 3 |
Earnest, сделал как ты сказала - предупреждения ушли. И что характерно приложение нормально отработало. НЕСМОТРЯ на то, что теперь я не поставил перед классом макрос AFX_CLASS_EXPORT, хотя он по ходу тождественнен __declspec (dllexport). Это нормальная практика экспортировать только функции класса, а работать с классом целиком? Это просто мне хочется доконца разобраться. И если я не экспортировал что-то (переменные или функции), находящиеся в классе, например private часть, это не скажется на работу экспортированных фукнций, ссылающихся при работе на неэкспортируемые? Это все можно проверить, но хочется увидеть теоретические доводы
По поводу литературы: этот источник мне понравился, предлагаю и тебе взглянуть - оценить. Альтернатива ему для меня в последнее время - только ты(смущаюсь...). Даже несмотря на то, что ещё не до конца разобрался, ставлю закономерный знак арифметичесой операции -------------------- я не гольфист - я хоккеист |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 87 Всего: 183 |
Нормальная. Экспортировать класс - значит экспортировать все его функции, а также все функции вложенных объектов и статические данные. Просто в первом случае ты экспортируешь все одним махом (для ленивых), в том числе и закрытые члены, во втором - управляешь экспортом. Реально экспортировать нужно только то, что прямо вызывает клиент, и что не объявлено инлайн. Все остальное вызывается уже из кода DLL. Кстати, по поводу инлайна будь осторожен: конструкторы и деструкторы объявляй явно и внутри файла cpp (т.е. прячь). В принципе, я бы вообще советовала избегать инлайна для экспортируемых классов, по крайней мере пока не разберешься полностью в происходящем. Т.к. инлайны имплементируются в вызывающем коде (т.е. в другом модуле), и могут вызвать всякие недоразумения. Скажем, есть паблик инлайн метод, который ты не экспортируешь, т.к. он инлайн. Но он, в свою очередь, вызывает какой-то приватный метод, не экспортированный. И линкер начинает орать насчет последнего, хотя вроде клиент его сам не вызывает. Ну нравится, так и пользуйся. В конце концов, есть темы, где сложно все хорошо объяснить без разночтений. Сама смотреть не буду, в лом, да и некогда. Кстати, MSDN все же почитай про DLL - все же это первоисточник. Там написано действительно все, хотя сложновато конечно: во-первых, английский, а во-вторых - много букв. Я в свое время распечатала себе темы про DLL, так получилась солидная такая книга... Но куда деваться... -------------------- ... |
|||
|
||||
| takedo |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 501 Регистрация: 1.6.2005 Репутация: нет Всего: 3 |
Earnest, Ещй раз спасибо, вроде бы теперь все более ли менее понятно стало. Про MSDN - ты конечно права, но как сама понимаешь с моим немецким тяжело... Поэтому читаю Рихтера, Мешкова, Earnestа. А по поводу источника - тебе там конечно ничего нового не почерпнуть, но как модератору форума возможно и будет польза(чтобы послать сразу туда
В общем, считаю для себя этот вопрос закрытым. Всем большое спасибо. -------------------- я не гольфист - я хоккеист |
|||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Visual C++/MFC/WTL | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |