В Delphi, при работе с COM-объектом можно обращаться к свойствам и методам объекта через точку. На VC++ соответственно стандарт — через GetIDOfName и Invoke.
Через это вопрос: Можно ли на VC++ получать доступ к свойствам и методам объекта через точку.
Здравствуйте, Versus-13, Вы писали:
V1>В Delphi, при работе с COM-объектом можно обращаться к свойствам и методам объекта через точку. На VC++ соответственно стандарт — через GetIDOfName и Invoke. V1>Через это вопрос: Можно ли на VC++ получать доступ к свойствам и методам объекта через точку.
Здравствуйте, algol, Вы писали:
V1>>В Delphi, при работе с COM-объектом можно обращаться к свойствам и методам объекта через точку. На VC++ соответственно стандарт — через GetIDOfName и Invoke. V1>>Через это вопрос: Можно ли на VC++ получать доступ к свойствам и методам объекта через точку.
A>Можно, но не через точку, а через -> , см. директиву #import
Не вижу, кстати, причин для хохотушек. Ничего не мешает оборудовать обработку библиотеки типов в #import врапперами, реализующими обертки позднего связывания. Другое дело, что это не сделано, но уровень вмешательства в язык не намного больший чем для #import раннего связывания.
Кстати, может понадобиться всяким людям, пишущим аддоны для экселя, или где там связывание только позднее. Это я шароварщикам говорю.
Здравствуйте, George Seryakov, Вы писали:
GS>Так вот, на VC++ позднего связывания нет. А есть только методы IDispatch, как совершенно справедливо отмечалось, Invoke() и все такое. GS>А #import, это для раннего связывания.
Так методы IDispatch — это и есть пресловутое "позднее связывание". Их, правда, существует два варианта — вызов по имени (GetIDsOfNames+Invoke) и вызов по ID (Invoke). Так вот при #import используется второй вариант. Но это также позднее связывание.
Здравствуйте, George Seryakov, Вы писали:
GS>Не вижу, кстати, причин для хохотушек. Ничего не мешает оборудовать обработку библиотеки типов в #import врапперами, реализующими обертки позднего связывания. Другое дело, что это не сделано, но уровень вмешательства в язык не намного больший чем для #import раннего связывания.
GS>Кстати, может понадобиться всяким людям, пишущим аддоны для экселя, или где там связывание только позднее. Это я шароварщикам говорю.
Там и так позднее связывание через IDispatch, а в С++ кто в своем уме будет пользоватся поздним связыванием, если можна все делать через раннее связывание.
Здравствуйте, Аноним, Вы писали:
А>Там и так позднее связывание через IDispatch, а в С++ кто в своем уме будет пользоватся поздним связыванием, если можна все делать через раннее связывание.
А вот если нельзя через раннее: нету библиотеки типов для стороннегно COM-объекта к примеру ...
Vi2>Так методы IDispatch — это и есть пресловутое "позднее связывание". Их, правда, существует два варианта — вызов по имени (GetIDsOfNames+Invoke) и вызов по ID (Invoke). Так вот при #import используется второй вариант. Но это также позднее связывание.
#import никак не оборачивает вызовы Invoke. Смысл выделенного непонятен. Может, ты путаешь с MFC? Её визард генерил обёртки именно так как ты рассказываешь...
А>Здравствуйте, George Seryakov, Вы писали:
GS>>Не вижу, кстати, причин для хохотушек. Ничего не мешает оборудовать обработку библиотеки типов в #import врапперами, реализующими обертки позднего связывания. Другое дело, что это не сделано, но уровень вмешательства в язык не намного больший чем для #import раннего связывания.
В этом плане очень сильно помогает ATL с его CComPtr<IDispatch>. Код получается — ну почти как на VB
GS>>Кстати, может понадобиться всяким людям, пишущим аддоны для экселя, или где там связывание только позднее. Это я шароварщикам говорю. А>Там и так позднее связывание через IDispatch, а в С++ кто в своем уме будет пользоватся поздним связыванием, если можна все делать через раннее связывание.
Я буду. Будет куда меньше проблем при переползании с одной версии Office на другую. А по скорости разница не заметна, ибо всё равно out-of-proc сервер.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Работа с COM-объектом через "точку"
От:
Аноним
Дата:
18.05.06 08:35
Оценка:
Здравствуйте, Left2, Вы писали:
L>Я буду. Будет куда меньше проблем при переползании с одной версии Office на другую. А по скорости разница не заметна, ибо всё равно out-of-proc сервер.
А что за проблема?
Так будет у тебя еще больше проблем, так как через Invoke ты не определишь на этапе компиляции что где то там параметры поменялись.
Здравствуйте, Left2, Вы писали:
L>#import никак не оборачивает вызовы Invoke. Смысл выделенного непонятен. Может, ты путаешь с MFC? Её визард генерил обёртки именно так как ты рассказываешь...
Если #import обнаруживает custom или dual интерфейс, то формируется вызовы через vtable, т.е. осуществляя раннее связывание:
Проблема в том что ObjectModel меняется от офиса к офису. И насколько помню частенько методы в интерфейсы добавляются "в середину" что вызывает потрясающие по эффекту неожиданности проблемы в run-time. А вот DISPID остаются старыми.
А>Так будет у тебя еще больше проблем, так как через Invoke ты не определишь на этапе компиляции что где то там параметры поменялись.
А вот параметры менются редко. Куда чаще добавляются новые функции.
Здравствуйте, Left2, Вы писали:
А>>Там и так позднее связывание через IDispatch, а в С++ кто в своем уме будет пользоватся поздним связыванием, если можна все делать через раннее связывание.
L>Я буду. Будет куда меньше проблем при переползании с одной версии Office на другую. А по скорости разница не заметна, ибо всё равно out-of-proc сервер.
Хотел бы я посмотреть, как вы перепишете на VC++ тысяч 10 строк VBA через IDispatch->Invoke().
Re[5]: Работа с COM-объектом через "точку"
От:
Аноним
Дата:
18.05.06 11:02
Оценка:
Здравствуйте, algol, Вы писали:
A>Хотел бы я посмотреть, как вы перепишете на VC++ тысяч 10 строк VBA через IDispatch->Invoke().
По идее имелось ввиду, что как то автоматом можна сгенерить враппер который будет делать эти вызовы через Invoke.
L>>Я буду. Будет куда меньше проблем при переползании с одной версии Office на другую. А по скорости разница не заметна, ибо всё равно out-of-proc сервер.
A>Хотел бы я посмотреть, как вы перепишете на VC++ тысяч 10 строк VBA через IDispatch->Invoke().
10 тысяч строк и с нуля-то написать тяжеловато, не находишь?
А писать буду примерно так:
Здравствуйте, Left2, Вы писали:
L>10 тысяч строк и с нуля-то написать тяжеловато, не находишь?
Нахожу, но VBA я упомянул, потому что проще сначала отладить алгоритм там, а потом уже переносить на C++. А кучу строк можно записать через Macro Recorder.
L>А писать буду примерно так: L>И далее в том же духе.
Для примера возьмем вот такую простую строчку на VBA:
При использовании #import это будет соответствовать:
int lastRow = m_pApplication->Cells->Find("*", (IDispatch*)m_pApplication->Range->Item["A1"], xlFormulas, vtMissing, xlByRows, xlPrevious)->Row;
Сколько строк это займет при использовании Invoke()? Здесь только вызовов 5 штук. Не забудьте еще, что все параметры придется конвертить в VARIANT и обратно. А все параметры функций вам придется искать в хелпе, потому что никакого Intellisence не будет. А потом будете долго бодаться с ошибками типа Invalid Parameter. В общем, если вы попытаетесь написать вручную через Invoke() что-нибудь сложнее, чем "Hello, World!", то флаг вам в руки.
Я в одном проекте использовал CComPtr<IDispatch>. Нужно было вызвать у офисного документа буквально пару методов/свойств, а импортить вордовый typelib не хотелось. Если надо дурнуть свойство или метод с малым кол-ом параметров — то в самый раз.
Здравствуйте, Vi2, Вы писали:
GS>>Так вот, на VC++ позднего связывания нет. А есть только методы IDispatch, как совершенно справедливо отмечалось, Invoke() и все такое. GS>>А #import, это для раннего связывания.
Vi2>Так методы IDispatch — это и есть пресловутое "позднее связывание". Их, правда, существует два варианта — вызов по имени (GetIDsOfNames+Invoke) и вызов по ID (Invoke). Так вот при #import используется второй вариант. Но это также позднее связывание.
Ну да. Но я про то, что это позднее связывание осуществляется ручками благодарного за это программиста, а не средствами языка. У VC++ позднего связывания нет.