![]() |
|
![]() ![]() ![]() |
|
SlimSlot |
|
|||
Новичок Профиль Группа: Участник Сообщений: 15 Регистрация: 27.7.2009 Репутация: нет Всего: нет |
Доброго времени суток.
Впервые на Вашем форуме, надеюсь задержусь и мне здесь помогут. Я только недавно стал изучать COM. И вот в то время как мне показалось я могу делать практические вещи я попробовал пообщаться посредством COM с Excel. Все вроде бы получается но есть таки несколько проблем. Во-первых все на практике оказалось не совсем так как писалось в книжках. Сейчас я затормозился на том, что после создания компонента и сразу его уничтожения, программа как бы не завершается. Такое ощущение что я что-то не так делаю с COM, да даже не ощущение, а уверенность. Вот код. Подскажите, что же все-таки не так?
В WinProc сначала выбирается пространство имен Excel, инициализируется библиотека COM - CoInitialize(NULL); После обработки этого сообщения вызывается CoUninitialize(); Все работает корректно, пока не доходит до return 0; оконной процедуры. Если запускать в обычном режиме, то после закрытия окна (WM_CLOSE) - окно таки разрушается, но программа не оканчивает свою работу. Я попробовал продебажить по шагам. Так вот после return происходит ошибка There is no source code available for the current location. О чем она говорит я так и не понял. Скажите, что можно сделать? Что я не так делаю? Это сообщение отредактировал(а) SlimSlot - 27.7.2009, 23:11 |
|||
|
||||
jonie |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 5 Всего: 118 |
-------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
SlimSlot |
|
|||
Новичок Профиль Группа: Участник Сообщений: 15 Регистрация: 27.7.2009 Репутация: нет Всего: нет |
Просто проект делал по шаблону...
Ну да ладно. Какова причина то? Ноль я не возвращаю, ничего не изменилось. Вообще существует ли какой-то нормальный суперклассический способ создания компонентов? Так как написано в книгах? |
|||
|
||||
jonie |
|
||||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 5 Всего: 118 |
а вообще выложи минимальный проект - поглядим.
-------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
||||||
|
|||||||
SlimSlot |
|
|||
Новичок Профиль Группа: Участник Сообщений: 15 Регистрация: 27.7.2009 Репутация: нет Всего: нет |
В общем ситуация такая.
CoInitialize и CoUninitialize я вызываю в Main. Попробовал опять продебажить. Когда я создаю компонент IDE меня в какой-то сторонни хедер. Там, после вызова OleRun создаются дополнительные потоки. В итоге получается что после возврата из main у меня остатется подвисшими еще четыре потока. Соответственно я попробовал ExitProcess - все заработало. Но причину я так и не познал. Во-первых если компонент сам создает какие-то потоки, почему он их не уничтожает? Я, как программист, знать не знаю что там делает сервер, почему я должен беспокоиться о потоках? Ок, допустим я должен. Каким образом я должен корректно уничтожить потоки, если они создавались сервером? Еслтественно с COM-компонентом я могу обзаться только с помощью интерфейсов. Покажите, что за ф-я-член уничтожает эти самые потоки. Мне очень интересно добить эту ситуацию, и не хочется тупо прнудительно завершать процесс в main. У кого какие мысли. Да тут проекта то. Ну представленный код в оконной процедуре. В main-е - цикл обработки сообщений и CoInitialize с CoUninitialize. Вот пожалуй и все. вот
|
|||
|
||||
jonie |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 5 Всего: 118 |
так ты и не завершаешь работу, ты уничтожаешь окно. PostQuitMessage(0) делай вместо DestroyWindow -------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
SlimSlot |
|
|||
Новичок Профиль Группа: Участник Сообщений: 15 Регистрация: 27.7.2009 Репутация: нет Всего: нет |
Да в этом косяк, но у меня еще есть сообщение WM_DESTROY, я немного попутал где вызвать PostQuitMessage, но да ладно. Мелочи. В общем и целом у меня таки есть PostQuitMessage.
Как я сказал, приложение не завершает свою работу потому не все потоки уничтожены. Проблема в этом и только в этом. Но почему COM-компонент так себя ведет? И почему таки я не могу создать наконец интерфейс обычным классическим способом. Может все косяки из-за этих чертовых умных указателей? И где вообще документация к COM-компоненту. Странно все это |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 8 Всего: 223 |
Приложение завершит свою работу при завершении main функции (main или WinMain), сколько бы там потоков не оставалось (при выходе из main стоит exit) |
|||
|
||||
SlimSlot |
|
|||
Новичок Профиль Группа: Участник Сообщений: 15 Регистрация: 27.7.2009 Репутация: нет Всего: нет |
Приложение (читай процесс) завершит свою работу, если 1. Будут уничтожены все потоки 2. Закрыты все хендлы процесса Только при соблюдении этих двух пунктов может быть корректный выход. В некоторых случаях этим может заниматься ExitProcess. Она начисто уничтожает все потоки процесса и закрывает хендлы. Если использовать сишный рантайм, по после возврата из WinMain будет вызвана та самая ExitProcess, поэтому процесс завершится в любом случае. Но я не использую сишный рантайм, поэтому по умолчанию у меня не вызывается ExitProcess, вместо этого WinMain завершает работу return-ом. Процесс остается жить пока он имеет хотя бы один поток. За уничтожением потока следует соответственно уничтожение процесса. Но если после уничтожения основного потока будет жить хоть один параллельный - процесс будет жить. Поэтому мой процесс и живет - после завершения основного потока, остается еще 4. |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 8 Всего: 223 |
Эти 4 потока создает COM инфраструктура. Они должны помереть при вызове CoUninitialize. Если этого не происходит, то что то не вызывается (например тот самый CoUninitialize)
|
|||
|
||||
SlimSlot |
|
|||
Новичок Профиль Группа: Участник Сообщений: 15 Регистрация: 27.7.2009 Репутация: нет Всего: нет |
CoUninitialize вызывается в WinMain перед return
CoInitialize тоже в Main |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 8 Всего: 223 |
Так, давайте рубить руку по частям - сотрите кусок
|
|||
|
||||
SlimSlot |
|
|||
Новичок Профиль Группа: Участник Сообщений: 15 Регистрация: 27.7.2009 Репутация: нет Всего: нет |
Я это в первую очередь сделал.
Я же говорю, если не трогать создание компонента - то все работает как часы. Как только создается компонент, сразу выскакивает еще четыре потока. Следовательно CoUninitialize и CoInitialize работает нормально. Что-то внутри компонента |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 8 Всего: 223 |
Создание 4х потоков - это нормально. Кстати, Excel в невидимом режиме - это что то
![]() ![]() Рекомендую позвать ExitProcess в конце ![]() |
|||
|
||||
SlimSlot |
|
|||
Новичок Профиль Группа: Участник Сообщений: 15 Регистрация: 27.7.2009 Репутация: нет Всего: нет |
Ну только это и остается.
А кто-нибудь может потестировать создание компонента Excel без сишного рантайма и без ExitProcess? Это да, как-то такое встречалось. Но представь обработку 150 файлов в видимом режиме, я однажды делал |
|||
|
||||
![]() ![]() ![]() |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: COM/DCOM/ActiveX/ATL/CORBA | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |