The [well known] dangers of indirection...
Both _com_ptr_t and CComPtr template classes make your life a lot easier when consuming COM components.
But if you have multi-threaded code that’s creating a lot of COM component at a very high rate, you might want to look for that old “Inside OLE, 2nd Edition” book and read page 244 again:
“If you need more than one object, call CoGetClassObject to obtain an IClassFactory pointer for that CLSID, and then call IClassFactory::CreateInstance as often as you want with the desired IID”
One of the Premier ISV we take care of had a very poor performance experience when running their software on a 4-cpu box, the performance was 1% of the one obtained on a 1-cpu box! Talk about scalability... Unacceptable.
We changed the code and sure enough, the contention on the 4-cpu box was dramatically reduced:
Loop execution time: 5 seconds. Calling IClassFactory:: CreateInstance() in a tight loop:
1 threads iterated: 3905135 times
2 threads iterated: 2736063 times
3 threads iterated: 3000978 times
4 threads iterated: 2918930 times
5 threads iterated: 3032113 times
6 threads iterated: 2856540 times
7 threads iterated: 3078300 times
8 threads iterated: 3185061 times
If anyone is still interested in those native code topics, tell me and I’ll post a bit more details.
P.D.: You can also read a similar Optimizations chapter on page 118 of Essential COM.
P.D.²: Keep in mind that even for in-proc scenarios (DLL), this might still be good to use IClassFactory if the component implementation has some kind of synchronization in its implementation of IClassFactory.