| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: WinAPI и системное программирование > Потоки и DLL |
| Автор: jsa 17.12.2007, 08:48 |
| HI All! столкнулся со следующей проблемой: есть нормальная обычная дллка, подключается динамически, эта дллка экпортирует функцию, которая, в свою очередь, создает поток, выполняющий определенную бизнес-логику, по завершению работы определенного экземпляра потока хотел прикрутить событие OnTerminate... НО, нетут-то было, нифига это событие не работает, стал разбираться почему... оказывается (вычитал у Пачеко), что событие OnTerminte работает в контексте основного потока, а никак не контексте самого потока, в этом вся и сложность! Где мне взять основной контекст, если поток запускается из динамически загружаемой библиотки - это одна проблема, вторая (наверное более сложная) - есть такое понятие как DLL Entry Point (о чем всезнающий алл прекрасно знает), а в частности DLL_THREAD_DETACH, где DLL_THREAD_DETACH будет работать (важно!) в контексте конкретного потока!!!(у того же Пачеко). И действительно!!! работает! НО, встает самая важная проблема - идентифировать поток, что бы получить доступ к публичным методам и свойствам (в этом вся соль - получить данные из потока, перед его уничтожением, когда execute завершен) Можно попробывать GetCurrentThread, но она(функция) возвращает псевдохендл потока, и необходимо сделать Duplicatehandle, как этим пользоваться? не догоняю! |
| Автор: Felan 17.12.2007, 09:27 |
| Хм... ни разу не пробовал делать потоки из длл... но что-то мне подсказывает, что ты сильно путаешь... Вопервых, неважно в каком контексте, но OnTerminate должно происходить. И если ты его назначаешь, то метод должен быть вызван. Если нелады с синхронизацией, то будут ошибки, но сам обработчик обязан вызываться. Но, если вдруг это и так, и он действительно из длл не вызывается, то возьми и сам вызови его при выходе из execute. Или можешь вообще свое событие сделать и его вызывать... |
| Автор: jsa 17.12.2007, 13:24 | ||
| весь смысл в том чтобы заработало событие OnTerminate, понятно что код можно вызвать в конце execute, но тут уже дело принципа - почему не работает OnTerminate опять же DLL_THREAD_DETACH предназначено не только для ShowMessage('thread finished') Добавлено через 1 минуту и 43 секунды
получить данные из потока, перед его уничтожением, когда execute завершен |
| Автор: Alexeis 17.12.2007, 15:57 |
| Возможно, что OnTerminate вызывается из OnIdle application, а application dll и exe разные, причем application dll мервый (т.е. не крутиться в очереди сообщений), потому OnIdle и не вызывается. Можно попробовать application dll заменить на application exe (присвоить указатели). Добавлено через 1 минуту и 59 секунд Это я предположил из тех соображений, что так Syncronize работает, вполне возможно, что OnTerminate работает аналогично ведь нужно же где-то основному потоку войти в критическую секцию и заблокироваться. |
| Автор: jsa 17.12.2007, 16:50 |
| Alexeis, попробую, может действительно поможет, спасибо за совет |
| Автор: Alexeis 17.12.2007, 17:29 |
| jsa, вообще ИМХО VCL и Dll вещи малосовместимые и неудобные для взаимодействия. Мне видится 4 пути развития. 1) VCL приложение WinApi Dll 2) VCL приложение BPl как аналог Dll (реализация VCL во внешней BPl) 3) VCL приложение, вся работа со стандартными компонентами исключительно внутри приложения, для наследников VCL определен необходимый интерфейс. Классы конструируются исключительно в Exe, а Dll получает к ним доступ через интерфейсы 4) И классика COM ActiveX. VCL Dll + VCL exe не клеится, да и криво дублировать код VCL. |
| Автор: jsa 17.12.2007, 19:08 |
| Alexeis, первый этап я еще могу представить, до 2 и 3 - я явно не дорос но все равно спасибо за наставление ЗЫЖ у меня VCL EXE + чистый DLL (без какого либо VCL) |
| Автор: Alexeis 18.12.2007, 23:28 |
TThread это VCL. |