I have two STA threads that make calls to a COM server and so I get back two different COM proxy pointers to the same COM object. Is there a way check equality in this case given pointer comparison is out of the question?
Asked
Active
Viewed 84 times
0
-
3Have one thread marshal its pointer to the other thread, then have that other thread perform COM identity comparison (which means, explicitly query both pointers for `IUnknown` then compare resulting `IUnknown*` pointers for equality). – Igor Tandetnik Jan 13 '17 at 01:04
-
@IgorTandetnik: I may be wrong, but I don't think that would work. In order for two STA threads to access the same COM object in the first place, the object has to be marshaled to at least one of the threads, maybe both, and the marshal is a proxy. The identity comparison would be checking the `IUnknown` pointer of the proxy, not the underlying COM object. When sharing a COM object across apartments, consider storing it in `IGlobalInterfaceTable`, pass around the token to each thread so the COM object can be marshaled to each one, and then compare the tokens for equality, not the proxies. – Remy Lebeau Jan 13 '17 at 01:14
-
1@RemyLebeau COM marshaling never creates two proxies to the same object in the same apartment. When you marshal the same object to a particular apartment twice, perhaps via different routes, COM makes sure that the end result is two pointers to the same proxy object; COM identity is maintained. – Igor Tandetnik Jan 13 '17 at 01:21
-
@IgorTandetnik: perhaps, but that would not be the case if the COM object is created in the MTA or STA 1 and is then marshaled to STA 2 and 3, and 2 and/or 3 need to do the comparison. – Remy Lebeau Jan 13 '17 at 01:26
-
2@RemyLebeau STA 2 would have to marshal the pointer to STA 3 and have the latter do the comparison (or vice versa). It is physically impossible to perform the comparison any other way: it would be illegal (in violation of COM rules) to just pass a raw pointer directly from one apartment to the other and have the latter call `QueryInterface` on it. Though I grant you that a wiser course of action might be to revisit the design of the application so that it doesn't lose track of its COM objects in the first place. – Igor Tandetnik Jan 13 '17 at 01:42
-
Isn't this what IMoniker is for? – andlabs Jan 13 '17 at 03:30
-
2I second everything that @IgorTandetnik says. First, you need to get the references into the same apartment, because COM pointers can be used only in their containing apartment. Once they are in the same apartment, you can use COM identity. – Raymond Chen Jan 13 '17 at 05:02
-
This has been a very insightful discussion. I was investigating performance issues and experimenting with creating an STA background thread scheduler. when I noticed a caching mechanism we use was duplicating objects. Those objects turned out to be COM proxies. I will investigate how to fix my performance issues without the use of the STA background thread scheduler. – noztol Jan 13 '17 at 18:33