Здравствуйте Михаил, Вы писали:
М>Пожалуйста, помогите решить проблему.
М>Есть куча указателей IUnknown, нужно определить ProgId или CLSID приложения, которое их предоставило. Просто имя модуля — уже на 100% устроит. Чтобы отсеять не нужные. Проблема в том, что часть из них может тормозить или висеть, т.е. не желательно QueryInterface или любое другое обращение к каждому по очереди. Есть ли такие функции в COM или в kernel, которые дадут нужную информацию прямо по значению указателя? Понятно, что Windows сама это делает, иначе не работала бы, но как?!
Так как есть Custom Marshaling, то в общем случае это задача точно не решается. И даже в частном случае — стандартный маршалин, Windows тебе скорее всего не даст этой инфо, это исключительно внутренее, и повода этo показывать нет, а то народ начнет извращаться — как ты это хочешь сделать :))
Если тебе надо выяснить умер ли объект, то надо его пинговать, и при этом IUnknown для этого не подходит, так как он может быть оптимизирован маршалерром и работать даже когда связи с объектом нет. Так что надо какой-то более конкретный интерфейс, со специальным методом, который ничего не делает, и просто проверяет соединение. При это важно уметь прерывать этот вызов, так как иначе он может висеть до бесконечности — я тестировал, весит.
Я раньше дискутировал проблему прерывания, основными результами было:
— посмотреть
http://www.optim.ru/cs/2000/4/com_htm/com_2.asp
— использовать IMessageFileter::MessagePending, если это STA (Single Thread Apartment), или
— использовать CoCancelCall (это работает для любой модели апартмента), и при этом если ты программируешь под Windows 2000, чтобы не создавать дополнительных ниток можно использовать Waitable Timer (см. ::CreateWaitableTimer)
И если ты не хочешь последовательно проверять все объекты, то надо создать кучу ниток для проверки их параллельно — так должно быть намного эффективнее, особенно если речь идет о сетевых соединениях.
-Zork