Создание с помощью С# управляемого
В целях сравнения предыдущая программа клиента на управляемом C++ реализована снова, теперь уже на С#. Новая реализация приведена ниже. Выдача новой программы, естественно, та же, что и у старой. Как и предыдущий пример, новая программа интересна прежде всего тем, что ей не нужна сборка из метаданных. Следовательно, не нужно ни добавлять ссылку к проекту, ни инсталлировать сборку. Вместо этого, информация о типе разыскивается интерпретатором динамически, т.е. во время выполнения, с помощью отражающего программного интерфейса приложения (reflection API).
//ManagedCSharpCOMClientWithoutMetadata.cs
using System;
// использование Системы;
using System.Reflection;
namespace ManagedCSharpCOMClientWithoutMetadata
// пространство имен
ManagedCSharpCOMClientWithoutMetadata
{
public class Test
// общедоступный класс Испытание
{
public static void Main(string[] args)
// общедоступная статическая Главная (строка параметров)
{
Type type; // Тип типа
Object obj; // Объект
Object[] argArray = new Object[2]; // новый Объект [2]
type = Type.GetTypeFromProgID( // Тип
"LegacyCOMServer.LegacyCOMObj.1");
obj = Activator.Createlnstance(type);
// obj = Активатор.
Createlnstance (тип);
argArray[0] = 3;
argArray[l] = 4;
Object sum = type.InvokeMember(
// Объект сумма = тип.InvokeMember (
"AddEmUp",
BindingFlags.InvokeMethod,
null, // пустой указатель
obj,
argArray
) ;
Console.WriteLine(sum); // сумма
}
}
}
Если вы запустите эту программу, то увидите выдачу, которая в точности совпадает с выдачей предыдущих программ клиентов, построенных на основе модели компонентных объектов Microsoft (COM).
Размещение и маршалинг
В приведенных нескольких примерах было рассказано, как на основе модели компонентных объектов 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].
CompEbook.ru Железо, дизайн, обучение и другие