Am I calling a .NET object or a COM object?

An interesting question arose today. Let's say I have a .NET object that implements a specific IMyInterface interface and also COM Visible.

Now I load this type from its ProgID and impose it on a strongly typed interface, for example:

IMyInterface objEarlyBound = null; Type t = Type.GetTypeFromProgID("My.ProgId"); objLateBound = Activator.CreateInstance(t); objEarlyBound= (IMyInterface)objLateBound; objEarlyBound.Method(); 

If I execute the above code when objEarlyBound.Method () is executed, do I call in a COM object or directly in a .NET object? How can I prove it anyway?

+7
c # com-interop
source share
2 answers

You cannot prove much in any case - it is an internal choice of implementation that was intentionally hidden from you.

objEarlyBound and objLateBound must have the same identifier, i.e. == will return true on them. Therefore, from each of them you can always get another one, as well as for any other interfaces that they support, as well as if you assigned any of them to object . But this does not prove anything.

If you directly refer to an assembly containing a class opened via COM as My.ProgId , you can say:

 IMyInterface objEarlyBound = new MyClassExposedThroughCOM(); 

At this point, CLR COM support is not required at all. But then you can transfer this object to some external COM library, and at that moment the CLR will create a CCW to communicate with the object. And by doing this once, it can always return to the same CCW for any CLR object.

So, to associate this with your example, you start with RCW around the COM object, you pass it to the interface, and at that moment the CLR can (as we all know) request a special internal COM interface, which, if found, allows it to capture an internal CLR object and thus completely bypass COM since then. If at any time he needs to return to the CCW, he can do it, because he must be able to do it at any time while working in a different direction.

I tried to set a breakpoint in the QueryInterface function of a C ++ COM object to see what the CLR was looking for. Basically, he tries a lot, some of which I cannot immediately determine, so he may very well β€œsniff” for another CLR object. To do this, it makes sense to do this in order to avoid the crazy COM sandwich situation in which the CLR link points to RCW, which points to CCW, which points to the CLR object. This can be simplified if the CLR reference is simply pointed directly to the CLR object.

Actually, now I think about it, he does not need to query to find out: he has a global CCW table that he previously generated, so he can just look for any new IUnknown there. COM objects should always return the exact address for IUnknown so that it can be used to compare the identity of the object. Therefore, the CLR can always recognize the COM object that it implements, and get the corresponding CLR object.

By the way, all this discussion assumes that the COM object is in the process. If this is outside the process, the situation is completely different; each process has its own CLR instance and therefore can also use the COM implementation for interprocess sorting.

+2
source share

RCW should be (from what I know) a special type of System .__ ComObject, however, probably what you want to do is call Marshal.IsComObject , which will tell you whether the object is a runtime shell or not. In a quick scan, an object created by COM through this route ends up as a direct managed object and loses the COM wrapper.

+3
source share

All Articles