简体   繁体   中英

Is it safe to use C++ “operator new” rather than CoCreateinstance to create a COM object?

this is probably a noob COM question, but googling this raises more questions than providing answers:

Is it safe to use "operator new" instead of CoCreateInstance for a local COM instance?

What I've done:

  1. I implemented the IOperationsProgressDialog interface http://msdn.microsoft.com/en-us/library/windows/desktop/bb775368(v=vs.85).aspx by using public inheritence and thereby also implemented the IUnknown interface.

  2. I created an instance via "new RecyclerProgressCallback" and put it into a COM-Ptr for life-time management. "RecyclerProgressCallback" is the name of my derived class.

  3. I'm using this instance in IFileOperation::SetProgressDialog http://msdn.microsoft.com/en-us/library/windows/desktop/bb775803(v=vs.85).aspx

Summary: My approach "seems" to work, but I don't trust it, there's just too much disconcerting information around COM object creation to rely on the observable behavior only.

Are there any subtle risks, fallacies or other problems? Thanks!

I've even put them on the stack. Andrey's answer (now deleted) incorrectly suggested that it is unsafe, because you bypass COM reference counting. This is faulty reasoning. COM doesn't count references; it delegates the responsibility to you. You have to call delete , or free() , or whatever your language uses, after COM calls your Release method on its last interface. The important word is after . Not when , because you're not obliged to do so immediately.

Similarly, CoCreateInstance is a long detour because COM is language-neutral and doesn't know whether an object must be created with malloc or new . You do, so just bypass the whole COM logic.

It depends what exactly you are instantiating. When you are supposed to provide a COM pointer noone asks you whether it is instantiated with COM API, or new , or it can sometimes be even object on stack (provided that you manage to ensure it is not destroyed on stack before all references are released).

So the answer is yes, you can use new and it would be fine. However, it should be a valid COM interface anyway, it should implement reference counting and QueryInterface the way COM objects do.

CoCreateInstance API will look at the registry find the module that match specified CLSID , load it and the through a mechanism(it depend whether your code is DLL or EXE ) it will call some functions to create your object. So for your code in order to make CoCreateInstance to work, you should write a class that implement IClassFactory interface of COM and register it in the registry and then call CoCreateInstance that do a couple of extra work with your code to at least do your lovely operator new , then yes of course it is safe. In general it is always safe to call operator new of implementation of source interfaces(interfaces that only declared for callback) in your code and this is also the preferred way.

This will work fine. This is how a COM server would typically create its objects internally (at least one written in C++). From your point of view, the RecyclerProgressCallback class is just some C++ code. You can treat it as any other class in your program.

That being said, COM is a minefield of subtle gotchas. I can't promise that you won't encounter problems with your class, but I can assure you that those problems will be unrelated to your use of operator new.

It's generally not safe, not just because of reference counting but also because of marshalling: the class may have a threading model that requires marshalling. CoCreateInstance will create a proxy and stub if that's the case, whereas new will not.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM