I have been writing a C++ program where I am creating a shortcut link for an exe file, and to do that I need to write the CoInitialize(0); at the starting. And without it the code does not work. Can someone help me to know why we use it?
I just want to know why we use this function.
CoInitialize(), and the extended and more recommended version CoInitializeEx(), are used to initialize the COM library for the current thread:
Initializes the COM library on the current thread
...
New applications should call CoInitializeEx instead of CoInitialize.
It has to be called for each thread that uses COM.
Note that CoInitialize() identifies the concurrency model as single-thread apartment (STA), whereas with CoInitializeEx() you have the freedom to specify the concurrency model.
More about COM threads and other related issues: Processes, Threads, and Apartments.
In case you are not familiar with COM (from the documentation):
COM is a platform-independent, distributed, object-oriented system for creating binary software components that can interact. COM is the foundation technology for Microsoft's OLE (compound documents) and ActiveX (Internet-enabled components) technologies.
If your program requires calling one of the initialization functions above, it means that either you directly, or any library you use, are using COM.
Note that each successful call to CoInitialize/Ex() must be matched with a call to CoUninitialize().
Edit:
As #IInspectable commented, using a COM object on a thread does not strictly require calling CoInitialize/Ex().
But, since COM objects have threading requirements as noted above, calling it ensures that the current thread uses the proper COM concurrency model.
See Why does CoCreateInstance work even though my thread never called CoInitialize? The curse of the implicit MTA.
Related
This thread is great at explaining STA vs MTA for COM, however it doesn't address how to code for such or when to use one or the other, and only just discusses technicalities about COM apartments being used by thread-safe objects or not. I'd be willing to bet most users just want to know how to use the Win API through COM without any COM objects shared among multiple threads.
Should you use STA always if your COM objects aren't shared among threads, and your code makes use of multiple threads or a single thread each with its own COM object instances, none of the objects shared? Does it depend on the object you are using? If you don't always use STA for such when do you use MTA? Do you ever need a message pump in this case?
In my case I use the Task Scheduler API (ITaskService) and the Shell Links/Create Shortcut API (IShellLink) from the main GUI thread (using the Qt Framework), and the File Operation API (IFileOperation) and the Volume Shadow Copy Service API from a worker thread.
I call CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); from each thread before initializing and using the COM objects and CoUninitialize(); after. Is this proper usage of COM? Would the same apply using COM objects from the main GUI thread without a worker thread?
For making outbound COM calls to objects that you instantiated via CoCreateInstance, STA should be good enough, and is almost a must for your GUI thread (the one that has a GetMessage/DispatchMessage loop).
MTA starts to become relevant when hosting your own thread safe COM objects that are expected to be invoked from other processes.
The documentation for IFileOperation states this:
IFileOperation can only be applied in a single-threaded apartment
(STA) situation. It cannot be used for a multithreaded apartment (MTA)
situation. For MTA, you still must use SHFileOperation.
See all, this link: INFO: Calling Shell Functions and Interfaces from a Multithreaded Apartment
I suspect what the documentation is really trying to say is this:
The class implementing IFileOperation is not thread safe
It's ThreadingModel is declared "apartment" in the registry and will incur marhsalling overhead if accessed from an MTA thread.
On our application, have used ITaskScheduler on the main STA thread. And we use IFileOperation on a background STA thread that has its own message pump.
Some other links that I think are very useful:
https://support.microsoft.com/en-us/help/150777/info-descriptions-and-workings-of-ole-threading-models
https://devblogs.microsoft.com/oldnewthing/?p=22603
Consider writing a reusable custom function that inside its body creates COM objects and calls methods to some COM interfaces. For this to work properly, CoInitializeEx and the matching CoUninitialize APIs must be called.
Calling those COM initialization and cleanup APIs inside the function's body would hide a COM implementation detail to the caller, and would remove a burden from the caller as well.
But is calling CoInitializeEx and the matching CoUninitialize inside function's body considered a good coding practice?
Would calling those COM init/cleanup functions at the function-granularity level imply too much overhead for each function call?
Are there other drawbacks in this design?
It is a terrible practice and fundamentally wrong. What matters a great deal is the value for the 2nd argument (dwCoInit). It must be COINIT_APARTMENTTHREADED, often abbreviated to STA, or COINIT_MULTITHREADED (MTA). This is a promise that you make, cross-your-heart-hope-to-die style. If you break the promise then the program will die. Usually by deadlocking, not getting expected events or having unacceptably slow perf.
When you select STA then you promise that the thread is well-behaved and can support COM components that are not thread-safe. Fulfilling that promise requires that the thread pumps a message loop and never blocks. The common behavior of a thread that supports a GUI for example. The vast majority of COM components are not thread-safe.
When you select MTA then you don't promise any support at all. The component must now fend for itself to keep itself thread-safe. Often done automatically by having the COM infrastructure creating a thread by itself to give the component a safe home. A further detail that you need to take care of is marshaling the interface pointer, requires CoMarshalInterThreadInterfaceInStream() helper function or the more convenient IGlobalInterfaceTable interface. This ensures that a proxy is created that takes care of the required thread context switch.
MTA sounds convenient, but not without consequences, a simple property getter call can take as much as x10000 more time. Overhead imposed by the thread context switches and the need to copy any arguments and the return value across stack frames. And marshaling the interface pointer can easily fail, authors of COM components often don't provide the necessary proxy/stub or they intentionally omitted it because it is just plain too difficult or expensive to copy the data.
Key point is that the choice between STA and MTA can never be made by a library. It does not know beans about the thread, it did not create that thread. And cannot possibly know if the thread pumps a message loop or blocks. That's all code that is entirely out of the library's reach. Otherwise the exact reason that the COM infrastructure needs to know this as well, it likewise cannot make assumptions about the thread.
The choice must be made by the code that created and initialized the thread, invariably the app itself. Unless the library creates a thread for the purpose of making the calls safe. But then with the consequence of code always being slow. You remind the caller of your library that he didn't get it right by returning the inevitable CO_E_NOTINITIALIZED error code.
Fwiw, this is something you see back in the .NET Framework. The CLR always calls CoInitializeEx() before a thread can execute any managed code. Still a choice that must be made by the programmer of the app, or more typically the project template, done with the [STAThread] attribute on Main() or the Thread.SetApartmentState() call for a worker thread.
I need to call some COM APIs from a simple REST server using the REST SDK. It's similar to the BlackJack sample code.
Whenever I try to create a COM object I get an exception that CoInitialize has not been called. But where exactly can I initialize the thread that processes the REST request? I couldn't find any documentation.
I tried the constructor (BlackJackDealer in the sample) but that does not work:
BlackJackDealer::BlackJackDealer(utility::string_t url) : m_listener(url)
{
CoInitialize(0);
...
}
Tasks in the C++ REST SDK execute on the Windows Threadpool by default. Instead of trying to join threadpool threads to an STA (which should be considered an anti-pattern), you can either:
Specify a custom scheduler (deriving from pplx::scheduler_interface) when creating tasks that need to call COM methods. See pplxinterface.h for the interface declaration and windows_scheduler::schedule() inside pplxwin.cpp for how the default scheduler is implemented on various Windows flavors.
Manually marshall any COM interactions to a thread that you own and control (and have called CoInitialize on). This probably means something like having a global vector of std::function objects that you protect with the usual mutex/condition_variable dance.
You may need to perform manual marshalling even if you go the custom scheduler route, but the custom scheduler will interoperate better with the existing task-based APIs.
If I call the same COM function from multiple threads to an in proc COM Dll, how thread safe is that?
Do all my objects in the COM DLL also need to be thread safe for this to work reliably?
COM takes care of threading on behalf of the COM server. The server publishes the kind of threading it supports with the ThreadingModel registry key. Very common settings are Apartment or Both. Free is very rare. A missing key is equivalent to Apartment.
COM requires a single-threaded apartment (STA) for apartment threaded servers. If you don't provide one (CoInitialize/Ex call) then it will create a dedicated thread for the server. A hard requirement for an STA thread is that it also pumps a Windows message loop. The message loop is the mechanism by which COM automatically marshals a method call from one thread to another.
So, the general answer to your question is, yes, it normally is thread-safe. There are still things that can go wrong. Deadlock is possible when a call is made from a worker thread but the STA thread isn't pumping. Or the server could be fibbing about the ThreadingModel it registered. Not uncommon with servers implemented in .NET. They get registered as Both, but there are few .NET classes that are actually thread-safe.
See this very detaled article. Basically COM will take care of synchronization - you don't need to bother. However in certain cases the consumer can experience significant slowdown because of synchronization.
Depends upon the COM objects threading model. If its free threaded then you are responsible for thread safety. If its in a single threaded apartment then you can only call it from one, and if it's in a multithreaded apartment, then you can can but as always you have to consider the implications for the object's state. there is a very good answer on SO Could you explain STA and MTA? explaining this.
In C# there is a method SetApartmentState in the class Thread.
How do I do the same thing in C++?
For unmanaged processes, you control the apartment model used for a thread by passing appropriate parameters to CoInitializeEx(). Larry Osterman wrote up a great little guide to these:
...
When a thread calls CoInitializeEx (or
CoInitialize), the thread tells COM
which of the two apartment types it’s
prepared to host. To indicate that
the thread should live in the MTA, you
pass the COINIT_MULTITHREADED flag to
CoInitializeEx. To indicate that the
thread should host an STA, either call
CoInitialize or pass the
COINIT_APARTMENTTHREADED flag to
CoInitializeEx.
...
-- http://blogs.msdn.com/larryosterman/archive/2004/04/28/122240.aspx
c++ doesn't have built in thread support. What you are looking for depends on how you are implementing threads in your application. Win32? pthreads? boost::threads? Whichever API you are using will determine the answer to your question.
EDIT: looks like this may have an example for you: http://msdn.microsoft.com/en-us/library/system.threading.apartmentstate.aspx
It looks like it applies to managed c++.