Можно ли использовать С++ "оператор new", а не CoCreateinstance для создания COM-объекта?
это, вероятно, проблема с noob COM, но в googling возникает больше вопросов, чем ответов:
Безопасно ли использовать "оператор new" вместо CoCreateInstance для локального экземпляра COM?
Что я сделал:
Сводка: мой подход "кажется" работает, но я не верю в него, слишком много неприятностей в отношении создания COM-объекта, чтобы полагаться только на наблюдаемое поведение.
Есть ли какие-то тонкие риски, заблуждения или другие проблемы? Спасибо!
Ответы
Ответ 1
Я даже положил их в стек. Ответ Andrey (теперь удален) неправильно предложил, что он небезопасен, потому что вы обходите подсчет ссылок COM. Это ошибочное рассуждение. COM не учитывает ссылки; он делегирует вам ответственность. Вы должны называть delete
или free()
, или независимо от того, что использует ваш язык, после того, как COM вызывает ваш метод Release
на своем последнем интерфейсе. Важное слово - после. Не когда, потому что вы не обязаны делать это немедленно.
Аналогично, CoCreateInstance
- длинный обход, потому что COM нейтрален для языка и не знает, должен ли быть создан объект с помощью malloc
или new
. Вы так просто обходите всю логику COM.
Ответ 2
Это зависит от того, что именно вы создаете. Когда вы должны указывать COM-указатель, никто не спрашивает вас, создается ли он с помощью COM API или new
, или иногда может быть даже объектом в стеке (при условии, что вам удастся обеспечить, чтобы он не был уничтожен в стеке перед всеми ссылками выпущены).
Итак, да, вы можете использовать new
, и все будет хорошо. Однако он должен быть допустимым COM-интерфейсом в любом случае, он должен внедрять подсчет ссылок и QueryInterface
, как это делают объекты COM.
Ответ 3
CoCreateInstance
API будет смотреть на registry
найти модуль, который соответствует указанному CLSID
, загрузить его и через механизм (зависит от того, является ли ваш код DLL
или EXE
) он вызовет некоторые функции для создания вашего объекта. Итак, для вашего кода, чтобы заставить CoCreateInstance
работать, вы должны написать класс, реализующий IClassFactory
интерфейс COM
, и зарегистрировать его в реестре, а затем вызвать CoCreateInstance
, которые выполняют пару дополнительных работ с вашим код, по крайней мере, сделать ваш прекрасный operator new
, тогда да, конечно, это безопасно. В общем, всегда безопасно вызывать operator new
реализации интерфейсов source
(интерфейсы, которые только объявили для обратного вызова) в вашем коде, и это также является предпочтительным способом.
Ответ 4
Это будет работать нормально. Так как COM-сервер обычно создает свои объекты внутри себя (по крайней мере один написан на С++). С вашей точки зрения, класс RecyclerProgressCallback - это всего лишь код С++. Вы можете рассматривать его как любой другой класс в своей программе.
Говоря это, COM - это минное поле тонких зачисток. Я не могу обещать, что вы не столкнетесь с проблемами с вашим классом, но я могу заверить вас, что эти проблемы не будут связаны с вашим использованием нового оператора.
Ответ 5
Как правило, это не безопасно не только из-за подсчета ссылок, но и из-за сортировки: класс может иметь модель потоковой передачи, которая требует сортировки. CoCreateInstance создаст прокси и заглушку, если это произойдет, тогда как new
не будет.