В приведенных нескольких примерах было рассказано, как на основе модели компонентных объектов Microsoft (COM) с помощью управляемого C++ создавать такие клиенты, которые получают доступ к существующему компоненту LegacyCOMObj, построенному на основе модели компонентных объектов Microsoft (СОМ), но совсем не уделялось внимание вопросам размещения и маршалинга. Нам не пришлось заниматься этими вопросами именно потому, что интерфейс ILegacyCOMObj имел атрибут dual (двойственный) в файле LeagcyCOM-Server.idl. Атрибут dual (двойственный) в модели компонентных объектов Microsoft (СОМ) указывает на необходимость автоматического маршалинга для интерфейса, основанного на информации из библиотеки типов. Двойственные интерфейсы встречаются очень часто, и именно они используются по умолчанию в генерируемых Мастером библиотеки шаблонных классов ATL (ATL wizard) компонентах, основанных на модели компонентных объектов Microsoft (COM). Компоненты, основанные на модели компонентных объектов Microsoft (COM), в Visual Basic 6.0 также создаются с двойственным интерфейсом. Однако если нет необходимости вызывать компоненты, основанные на модели компонентных объектов Microsoft (COM), клиентами с динамическим связыванием, реализация с помощью чисто v-табличного интерфейса может оказаться более удобной и гибкой. Таким образом, не все действующие серверы на основе модели компонентных объектов Microsoft (COM) предлагают только двойственный интерфейс. Поэтому может понадобиться маршалинг. Если его не предусмотреть, то управляемая программа клиента вызовет исключение InvalidCastException при попытке вызова метода интерфейса, для которого не указан маршалинг. Проблема состоит в том, что если клиент .NET размещен отдельно, то маршалинг для него необходим. Ниже для этой проблемы предлагается несколько решений. Заметим, что решения 1 и 2 могут оказаться неподходящими для существующих программ, особенно если у вас нет исходных текстов, или это неприемлемо для других клиентов, или невозможна повторная инсталляция.
1. Пометьте IDL (язык описания интерфейсов) для интерфейса как dual (двойственный) и заново реализуйте сервер на основе модели компонентных объектов Microsoft (COM).
2. Пометьте IDL (язык описания интерфейсов) для интерфейса как oleautomation и настройте сервер на основе модели компонентных объектов Microsoft (COM) так, чтобы все его типы параметров были дружественными к oleautomation.
3. Постройте и зарегистрируйте динамически подключаемую библиотеку (DLL) заместителя или заглушки для интерфейса так, чтобы выполнялся маршалинг.
4. Пометьте главный метод Main в клиенте на С# атрибутом [STAThreadJ или [MTAThread] (B зависимости от ситуации), чтобы поместить его в ту же потоковую модель, что и сервер на основе модели компонентных объектов Microsoft (СОМ). Например, в приведенных выше сценариях, если атрибут dual (двойственный) не используется в сервере на основе модели компонентных объектов Microsoft (COM), то для решения проблемы можно использовать атрибут [STAThread].