Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Системное программирование и WinAPI > PlugThisAPI )) или Окна в ДЛЛ |
Автор: MoZy 15.7.2006, 18:45 |
Суть моего вопроса (подробно): Допустим у меня реализован так сказать приложение-провайдер. В том смысле, что оно должно осуществлять роль посредника между сервером и плагинами, которые подключаются к этому самому приложению. Плагины будут представлять собой сетевые игрушки и другие фенечки. Сами по себе они будут лишь передавать и получать данные от моего "провайдера". С этим проблем нет. Ну вобщем это все не важно. Важно то что я не могу реализовать обыкновенную WinMain ну и Proc'едуру главную. Вобшем ДЛЛка моя не хочет быть ни чем, кроме библиотеки. Так как все-таки окошки, процедуры и другие подобные вещи сделать в ДЛЛ? вобщем я в растерянности... помогите. |
Автор: 586 15.7.2006, 19:12 | ||
Также, как и в exe. |
Автор: MoZy 15.7.2006, 20:05 | ||||
586, во-первых, я пишу в Dev-C++. Там варианты проектов Win32 DLL, Win32 GUI, ... . Если ставить ГУИ и откомпилить, то все окошки создаются и все нормально. НО создается ЕХЕшник. Но это не самое страшное, а страшно то, что при вызове етого ехешника как библиотеки, он и работает как библиотека и окна не создаются (то есть только функции и работают). А если компилить просто как ДЛЛ - окошек ни там ни тут не видно. Может есть какие-то особые штуки, которые надо сделать, чтобы все было хорошо? например, если
даю кусок кода. хедер с экспортными функциями приводить не буду - нет необходимости.
|
Автор: 586 15.7.2006, 20:22 |
Не понял. У тебя exe-шник в роли exe-шника и библиотеки сразу? Или WinMain экспортируется. Или тут слеплен код exe и dll????? |
Автор: MoZy 15.7.2006, 20:39 |
586, ![]() ой. неужели надо просто WinMain экспортировать и запустить из "мамы"? А процедуры не надо? |
Автор: Pilligrim 15.7.2006, 20:47 |
![]() Глянул я твой кусок кода, и не пойму как у тебя используется DllMain. К-а-к? |
Автор: 586 15.7.2006, 20:48 |
У тебя exe-шник который ты загружаешь, как dll, функцией LoadLibrary. WinMain у тебя исполняться не будет, а DllMain воспринимается, как обычная функция, и не исполняется. Вообще, у DLL ф-ция DllMain - это точка входа. У твоего exe точка входа - WinMain. А у исполняемого файла две точки входа быть не может! Поэтому exe просто загружается. |
Автор: MoZy 15.7.2006, 20:54 |
586, ну я компилю как DLL проект и получается DLL. Функции экспортируются нормально... Так что мне сделать? Экспортировать WinMain и отказаться от DLLMain? |
Автор: 586 15.7.2006, 20:58 | ||
Если у тебя exe - откажись от DllMain. Если у тебя dll - откажись от WinMain.
Хочешь запускать модуль отдельно - exe. |
Автор: MoZy 15.7.2006, 21:07 |
586, Я хочу, чтобы была связь между модулем и хостом. От WinMain'а отказаться не могу. Нельзя ли сделат ехе, но с расширением ДЛЛ? Кстати, с импортом функций проблем не будет? Добавлено @ 21:10 УРААА!!! Я отказался от DLLMain (я его раньше вообще не использовал, просто подумал, что может понадобиться при инициализации) и просто экспортировал WinMain и вызвал в хосте. И теперь у меня в ДЛЛке окошко есть! ![]() |
Автор: 586 15.7.2006, 21:21 | ||
Можно, но какой смысл в WinMain. Не должно. С экспортом WinMain могут быть проблемы. Я поэксперементировал, и вот что получил:
А функцию main вызываешь, как WinMain - c теми же параметрами. Она всего лишь передаёт управление WinMain. |
Автор: 586 15.7.2006, 22:13 | ||
Попробовал вот что:
Работает хорошо, но exe-шник сам запускаться не хочет. Делай DLL!!! |
Автор: MoZy 16.7.2006, 18:15 |
Спасибо, 586. Я все именно так и сделал. Но у меня возникли проблемы (в том числе и с пониманием сути вещей): 1. Если где-либо (хоть в WinProc, хоть в WinMain хоста) прописать что-либо (Beep или MessageBox) после вызова функции ModuleWinMain (или main как в твоем примере, 586), то это самое после сработает после того, как отдестроится окошко модуля. В чем прикол? 2. Если в хосте прописать FreeLibrary(Module_hInst), без предварительной команды модулю закрыть себя, то вылазит ошибка. Вопрос: это нормально? 3. Если же отдестроить окно хоста (то есть PostQuitMessage(0)) не делая выше сказанное, то: а) модуль продолжит свою работу; б) каким-то чудом хост будет попрежнему принимать сообщения от модуля и реагировать на них* *В модуле я по таймеру шлю сообщение хосту, а тот на это сообщение реагирует звуковым сигналом. Растолкуйте, пожалуйста, всю эту муть. |
Автор: 586 16.7.2006, 19:58 | ||||||
Если в диалоге прописать PostQuitMessage(0) и закрыть, окно exe тоже закроется. Но это в диалоге. В окне не знаю. |
Автор: MoZy 16.7.2006, 20:11 |
586, спасибо, что растолковал )) |
Автор: 586 16.7.2006, 20:21 |
Кстати, в винде есть такая прога - rundll32. Она запускает процедуры в библиотеках. rundll32.exe shell32.dll,ShellAboutA Таким образом можно запустить DLL, "без приложения". Может пригодится... |
Автор: MoZy 17.7.2006, 22:45 |
Теперь еще смешнее. При первой загрузке-выгрузке модуля все функции импортируются и выполняются нормально. Но при повторной загрузке выполняются все функции кроме ModuleWinMain. Проскакивает и окошек не делается. Вот такая проблема. И еще: если загрузить модуль, а потом его копию (то есть имя файла другое, а контент тот же), то вылазит ошибка 0хС000000000000005 Вот никогда бы не подумал, что будут такие проблемы... |
Автор: 586 17.7.2006, 22:50 | ||
Переходи на DLL!!!!!!!!! У exe проблемы с импортом! Для этого изобрели DLL. Вообще, зачем тебе функция WinMain? Хендл модуля ты знаешь, как и без него получить. |
Автор: MoZy 20.7.2006, 18:39 | ||
Что ты этим сказать хотел? Я и так гружу длл. просто в нем есть WinMain. 586, WinMain мне для того, чтобы окно в длл было (впринципе функцию хоть как назвать можно - от этого ниче не меняется). Поясню свою задачу: Мне необходимо из ехе загружать много разных длл, в которых свои маленькие программки. Нужно, чтобы нельзя ![]() Эти длл содержат и экспортируемые функции и свои окошки - если мелко сказать. А если нормально, то это целые проекты (в будущем, разумеется). Почему я не сделаю все наооборот? Почему в эти проекты не засуну длл моего ехе? Потому что я хочу, чтобы из одного моего ехе были доступны все эти проекты. Потому что так удобно и целостно. Но вот эта проблема с импортом... Нехочет второй раз импортировать мой ехе функцию WinMain модуля. Я ее уже и по другому называл, но ничего. Может еще процедуру обозвать по другому. Я в WinAPI недвано начал писать и с этими процедурами и функциями неполностью разобрался. 586, попробуй из ехе вызвать функцию WinMain (обзови ее по-другому) так, чтобы окно (ну или диалог), которое у тебя в длл, появилось. Потом выгрузи. И повтори операцию. Загрузится опять или нет? И если да, то скинь, плиз, пример длл и ехе. PS и почему никто больше постов не пишет? |
Автор: GremlinProg 20.7.2006, 20:27 |
В принципе понял, в чем суть, и могу порекомендовать экспортировать не WinMain функции, а наборы оконных классов, каждый класс будет описывать твой отдельный модуль, а из exe проекта нужно будет только подгружать твою библиотеку и создавать окно экспортированного класса. За примером долго ходить не надо, сама винда использует этот способ (32-битные версии). Если необходимо несколько окон, создавай несколько, но это уже в процедуре окна. Это еще удобно тем, что проблем с синхронизацией у тебя не будет. Посмотри, например, как реализована библиотека comctl32, которую использует большинство виндовых программ, посмотри, сколько она содержит классов, а каждый класс - это и есть отдельная подпрограмма - как раз то о чем ты и спрашивал. Но в сущности, библиотеки используются не для такой поддержки, как "приложение-провайдер", а просто для того, чтобы уменьшить объем кода в программах, уменьшить время её загрузки и уменьшить общее, потребляемое количество ресурсов в системе. |
Автор: Damarus 20.7.2006, 20:32 | ||
Так может быть проще запускать дополнительные потоки, в которых и будут работать "маленькие программки" ![]() |
Автор: MoZy 20.7.2006, 20:47 |
Damarus, всмысле Thread? Я еще не очень курю. Как я понял можно экспортить win main модуля, а потом создать для нее поток. Если я правильно понял, спасибо! |
Автор: Damarus 20.7.2006, 21:25 | ||||||
Принцип следующий: Dll'ка с первой программой (MoZyDll1.dll):
Dll'ка со второй программой (MoZyDll2.dll):
Exe, загружающий Dll'ки:
|
Автор: GremlinProg 20.7.2006, 21:48 |
Sleep(INFINITE) - весьма оригинально! библиотеки так не выгрузятся, нужно использовать WaitForMultipleObjects для обоих потоков, так что нужно, чтобы RunProgram из длл возвращали хотя бы дескрипторы потоков. Добавлено @ 21:51 но в любом случае нужно придумать еще и защиту: такую библиотеку подгрузит любая программа и вызовет RunProgram, имя будет известно, а в данном случае - и параметры тоже. |
Автор: Damarus 20.7.2006, 21:56 | ||||
GremlinProg, всё верно, но это просто пример ![]() Добавлено @ 22:59
Тоже верно, но полная защита не возможна. |
Автор: GremlinProg 20.7.2006, 22:20 |
Damarus, Sleep(INFINITE), WaitForMultipleObjects и т.п. - методы для синхронизации объектов, я как раз про них и говорил. Отлаживать такие приложения(в винде) довольно сложно, потому что они разделены во времени, поэтому и предложил более простой способ. Нужно хорошо знать принципы построения "параллельных" программ, чтобы писать корректный код. Не каждый может таким умением похвастаться. С защитой, конечно, согласен, но если так думать, то можно вообще не защищать софт. |
Автор: MoZy 21.7.2006, 17:37 | ||
Всем спасибо. Но потоки никак не изменили результат. Разве что их стало больше. Меня впринципе любой вариант устраивает. И импорт WinMain'a, и импорт функции, вызывающей WinMain, и создание потока с импортируемой функцией WinMain, и создание потока с импортируемой функцией, вызывающей WinMain, и импорт функции, создающей поток с WinMain. Но все это не работает так как надо! Почему-то при любой из этих махинаций WinMain второй раз не вызывается ![]() Извинияюся ![]() Оказалось функция вылетает при регистрации класса ![]() Ну вот. Как говорится: "Один дурак задаст столько вопросов, что сто мудрецов не ответят." Думаю тему надо закрыть. Но спешить не буду ![]()
Я уже реализовал протокол между хостом и плагинами, так что незная его плагином не воспользоваться ![]() Один OFF TOPIC: новички могут поднимать репутацию? ![]() |