In COM STA model, a hidden Window will be created with synchronized message pump operation. I have seen and debugged a couple of samples. My quesitons are,
1. Who (which party) is responsible for generating code to create the hidden Window and generate message pump (retrieve message one-by-one from message queue so that all processing to the component is synchronized)? Generated by COM Runtime (I suspect it generated by COM Runtime, because I have seen no code in the samples I studied to explicitly create the hidden Window)?
2. If it is created by the COM Runtime? When such code is generated? During call to CoInitializeEx and when specifiying parameter value for dwCoInit (COINIT_APARTMENTTHREADED or COINIT_MULTITHREADED)?
3. Where is the generated binary code? Injected by linker in the result COM DLL or EXE?
thanks in advance,
George
CBasicNet
March 25th, 2008, 01:42 AM
I cannot answer all your questions. But I can answer the one regarding the message pump.
I believe the hidden window is generated by the COM runtime but I have nothing to back me up. The message pump is originally 'there', whether you are writing a MFC or Win32 API client application. If you instantiate the COM object in a worker thread without the message loop, you cannot call any of the COM object's functions, iirc.
A worker thread with the message loop is actually known as the UI thread. A UI thread doesn't really need to have a window to be consider as an UI thread.
Read this article (http://www.codeguru.com/cpp/com-tech/activex/apts/article.php/c5533/)
//Example of a simple message loop
MSG msg;
while (GetMessage (&msg, 0, 0, 0))
DispatchMessage (&msg);
George2
March 25th, 2008, 04:16 AM
Thanks CBasicNet,
Another terms which makes me confuesd is marshell. From my study, if we call from one apartment to another STA apartment, even in the same process, the call needs to be marshelled.
I am confused,
1. Is marshell the same thing as to translate method call into windows message and push into STA hidden window?
2. If no to (1), what is the different function between marshell and the message window when we call a function in STA? I think a message windows is enough (for synchronize message processing) to STA, why involve marshelling as well?
I cannot answer all your questions. But I can answer the one regarding the message pump.
I believe the hidden window is generated by the COM runtime but I have nothing to back me up. The message pump is originally 'there', whether you are writing a MFC or Win32 API client application. If you instantiate the COM object in a worker thread without the message loop, you cannot call any of the COM object's functions, iirc.
A worker thread with the message loop is actually known as the UI thread. A UI thread doesn't really need to have a window to be consider as an UI thread.
Read this article (http://www.codeguru.com/cpp/com-tech/activex/apts/article.php/c5533/)
//Example of a simple message loop
MSG msg;
while (GetMessage (&msg, 0, 0, 0))
DispatchMessage (&msg);
regards,
George
Igor Vartanov
March 25th, 2008, 06:48 AM
Who (which party) is responsible for generating code to create the hidden Window and generate message pumpNone. The code which creates a hidden window resides in Windows OLE core. :) So it is neither generated nor injected correspondingly. It's merely called. ;)
Marshaling is a generic mechanism for cross-apartment interfacing, and it uses the hidden message window only in STA model. The marshaling generally takes care about transparent tranferring call arguments to target apartment (which may appear to be bound to the same thread as well as to another one, of the same process or even of the remote one) and corresponding call synchronization, if any implied by target apartment model.
Hope you'll enjoy this reading: Single-Threaded Apartment (http://msdn2.microsoft.com/en-us/library/ms680112(VS.85).aspx)
George2
March 25th, 2008, 09:44 AM
Thanks Igor,
I have read through the link you recommended, looks cool! But it does not cover marshelling in STA model.
1.
My question is, suppose we access function from one STA to another STA, the marshelling is only responsible for argument pack/unpack and return result pack/unpack?
2.
Is marshelling used also for the function of synchronization, like the hidden window message queue?
3.
Why marshell is needed even if we are using two STA inside the same process?
None. The code which creates a hidden window resides in Windows OLE core. :) So it is neither generated nor injected correspondingly. It's merely called. ;)
Marshaling is a generic mechanism for cross-apartment interfacing, and it uses the hidden message window only in STA model. The marshaling generally takes care about transparent tranferring call arguments to target apartment (which may appear to be bound to the same thread as well as to another one, of the same process or even of the remote one) and corresponding call synchronization, if any implied by target apartment model.
Hope you'll enjoy this reading: Single-Threaded Apartment (http://msdn2.microsoft.com/en-us/library/ms680112(VS.85).aspx)
regards,
George
Igor Vartanov
March 25th, 2008, 05:33 PM
STA-to-STA interfacing inevitably involves multithreading issues disregarding whether the process the same or not. On this reason marshalling is required as the generic mechanism for transporting call data and performing call synchronizations. STA benefits from this transparent synchronization support and never requires for any additional efforts of such kind.
I strongly suspect that marshaling code has optimization for the case of the same process' STA-to-STA communication, but nevertheless marshaling is still needed as the very generic OLE mechanism.
George2
March 26th, 2008, 12:54 AM
Thanks Igor,
I taken some hours to study and debug the material, looks cool.
http://www.codeproject.com/KB/COM/CCOMThread.aspx
Two more comments,
1.
When do we need to explicitly program message loop in STA thread? Like this code segment in the article. I have this question because I noticed all samples in the article, including the ones for cross-apartment do not explicitly get message, translate message and dispatch message.
DWORD WINAPI ThreadProc(LPVOID lpvParamater)
{
/* Initialize COM and declare this thread to be an STA thread. */
::CoInitialize(NULL);
...
...
...
/* The message loop of the thread. */
MSG msg;
while (GetMessage(&msg, NULL, NULL, NULL))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
::CoUninitialize();
return 0;
}
2.
For marshelling between apartments, I think all stub/proxy code are generated automatically by COM Runtime, right? No need for us to explicitly program stub/proxy code (e.g. using MIDL compiler do generate stub/proxy by ourselves)?
STA-to-STA interfacing inevitably involves multithreading issues disregarding whether the process the same or not. On this reason marshalling is required as the generic mechanism for transporting call data and performing call synchronizations. STA benefits from this transparent synchronization support and never requires for any additional efforts of such kind.
I strongly suspect that marshaling code has optimization for the case of the same process' STA-to-STA communication, but nevertheless marshaling is still needed as the very generic OLE mechanism.
regards,
George
CBasicNet
March 26th, 2008, 01:16 AM
You should ask the article author those questions; He is very knowledgeable about COM. Anyway, I had read all Lim Bio Liong's COM articles and Essential COM by Don Box. But as time passes by, the memory of those details will fade away, even though I had them at the finger tips when I first learn COM.
George2
March 26th, 2008, 01:40 AM
Thanks CBasicNet,
I also like his articles and the Inside COM book. I would like to have Essential COM book, but can not find in library or book store, is it too old book? :-)
I will try to ask question to him in his article discussion forum, and I would also like to discuss here since here are many knowledgable guys here.
You should ask the article author those questions; He is very knowledgeable about COM. Anyway, I had read all Lim Bio Liong's COM articles and Essential COM by Don Box. But as time passes by, the memory of those details will fade away, even though I had them at the finger tips when I first learn COM.
regards,
George
Igor Vartanov
March 26th, 2008, 04:54 AM
1.
When do we need to explicitly program message loop in STA thread?Never, in case you are talking about that hidden COM window message loop. COM component just implements its own interfaces and never intrudes into runtime support issues.
2.
For marshelling between apartments, I think all stub/proxy code are generated automatically by COM Runtime, right?Not exactly. Marshaling is mostly about the data transfer. In case in your call parameters you use use OLE Automation compatible data types with no exceptions the universal marshaler (a part of COM runtime) is able to generate proxy/stub on the fly. Otherwise the proxy/stub dll is generated by Visual Studio compiling tools (MIDL compiler), and the proxy/stub dll is used to the purpose.
(In fact, the proxy/stub dll idea was borrowed from RPC, as long as COM extends RPC concept.)
I'm sure the Troelsen's book I recommended to you some time ago covers all these issues.
George2
March 26th, 2008, 06:11 AM
Thanks Igor,
Your reply looks cool. During our discussion, let me summarize the process of method invocation from one apartment to another,
1.
Method call from other apartment to STA is pushed to the hidden window and parameters are converted to window message by COM runtime automatically and transparently;
2.
when the method is called by the owning STA thread, COM runtime will automatically and transparently convert message into function call parameters;
3.
when the method call returns in the STA, COM runtime will automatically and transparently convert return values of function into window message to the hidden window;
4.
the invoker from other apartment will receive the return result in the type they expected other than the raw window message, and COM runtime will be responsible for converting the window message to return value;
5.
For the whole process, marshelling works between the invoker and the windows message queue to pack/unpack data between two apartments.
My understanding correct?
Never, in case you are talking about that hidden COM window message loop. COM component just implements its own interfaces and never intrudes into runtime support issues.
Not exactly. Marshaling is mostly about the data transfer. In case in your call parameters you use use OLE Automation compatible data types with no exceptions the universal marshaler (a part of COM runtime) is able to generate proxy/stub on the fly. Otherwise the proxy/stub dll is generated by Visual Studio compiling tools (MIDL compiler), and the proxy/stub dll is used to the purpose.
(In fact, the proxy/stub dll idea was borrowed from RPC, as long as COM extends RPC concept.)
I'm sure the Troelsen's book I recommended to you some time ago covers all these issues.
regards,
George
George2
March 26th, 2008, 06:47 AM
Sorry for interruption again, Igor.
I have performed some search, and can not find an official document about what are you mentioned "OLE Automation compatible data types".
I am interested in it and it is very important concept, could you provide a link for the definition of what are compatible data types please?
Never, in case you are talking about that hidden COM window message loop. COM component just implements its own interfaces and never intrudes into runtime support issues.
Not exactly. Marshaling is mostly about the data transfer. In case in your call parameters you use use OLE Automation compatible data types with no exceptions the universal marshaler (a part of COM runtime) is able to generate proxy/stub on the fly. Otherwise the proxy/stub dll is generated by Visual Studio compiling tools (MIDL compiler), and the proxy/stub dll is used to the purpose.
(In fact, the proxy/stub dll idea was borrowed from RPC, as long as COM extends RPC concept.)
I'm sure the Troelsen's book I recommended to you some time ago covers all these issues.
regards,
George
Igor Vartanov
March 26th, 2008, 10:23 AM
IDispatch Data Types and Structures (http://msdn2.microsoft.com/en-us/library/ms221600(VS.85).aspx)
George2
March 27th, 2008, 12:32 AM
Thanks Igor,
I am wondering in order to use the default marshelling provided by COM Runtime, do we need to register type lib?
IDispatch Data Types and Structures (http://msdn2.microsoft.com/en-us/library/ms221600(VS.85).aspx)
regards,
George
Igor Vartanov
March 27th, 2008, 01:53 PM
Sure. Typelib is about whole component definition (coclasses, interfaces, etc.), but not about types only. :)
George2
March 28th, 2008, 12:12 AM
Thanks Igor,
I assume there are two popular ways to implement marshelling (beyond customized marshelling).
1. using MIDL compiler on IDL file to generate stub/proxy DLL;
2. register typelib.
What is the special benefits we can have in (1) compared with (2)? In my understanding, (2) should have some limitations compared with (1).
Sure. Typelib is about whole component definition (coclasses, interfaces, etc.), but not about types only. :)
regards,
George
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.