Вы не можете доказать в любом случае - это внутренний вариант реализации, который был умышленно скрыт от вас.
objEarlyBound
и objLateBound
должны иметь одинаковые идентификаторы, то есть ==
для них вернет true. Таким образом, от каждого из них вы всегда можете получить другой, и то же самое для любых других интерфейсов, которые они поддерживают, а также, если вы назначите один из них на object
. Но это ничего не доказывает.
Если вы прямо ссылались на сборку, содержащую класс, предоставляемый через COM, как My.ProgId
, вы могли бы сказать:
IMyInterface objEarlyBound = new MyClassExposedThroughCOM();
На данный момент поддержка COM в CLR вообще не требуется. Но тогда вы могли бы передать этот объект в какую-либо внешнюю COM-библиотеку, и в этот момент CLR создаст CCW для связи с объектом. И сделав это один раз, он всегда может вернуться к тому же CCW для любого данного объекта CLR.
Итак, чтобы связать это с вашим примером, вы начинаете с RCW вокруг COM-объекта, вы приводите его к интерфейсу, и в этот момент CLR может (насколько нам известно) запрашивать специальный внутренний COM-интерфейс, который, если найдено, позволяет ему получить доступ к внутреннему объекту CLR и, таким образом, полностью обойти COM. Если в любое время ему необходимо вернуться к CCW, он может это сделать, поскольку он должен иметь возможность сделать это в любое время при работе в другом направлении.
Я пытался поместить точку останова в функцию QueryInterface реализованного вручную COM-объекта C ++, чтобы узнать, что запрашивает CLR. По сути, он пробует много вещей, некоторые из которых я не мог сразу идентифицировать, так что это вполне может быть «сниффинг» для другого объекта CLR. Это имеет смысл для этого, чтобы избежать сумасшедшей ситуации с сэндвичем COM, в которой ссылка CLR указывает на RCW, который указывает на CCW, который указывает на объект CLR. Это можно легко упростить, просто указав ссылку CLR непосредственно на объект CLR.
На самом деле, теперь я думаю об этом, ему не нужно запрашивать это, чтобы выяснить это: у него есть глобальная таблица CCW, которую он сгенерировал ранее, так что он может просто найти любой новый IUnknown
там. COM-объекты должны всегда возвращать один и тот же адрес для IUnknown
, чтобы его можно было использовать для сравнения идентификаторов объектов. Следовательно, CLR всегда может распознать COM-объект, который он сам реализует, и получить соответствующий объект CLR.
Кстати, все это обсуждение предполагает, что COM-объект находится в процессе. Если это вне процесса, тогда ситуация совершенно иная; каждый процесс имеет свой собственный экземпляр CLR и поэтому может также использовать COM-реализацию межпроцессного маршалинга.