Практическое руководство. Создание оболочек вручную
Если решено объявлять COM-типы в управляемом исходном коде вручную, лучше всего начать с существующего файла языка IDL или библиотеки типов. В отсутствие файла IDL или при невозможности создания файла библиотеки типов можно имитировать COM-типы, создав управляемые объявления и экспортировав получившуюся сборку в библиотеку типов.
Имитация COM-типов из управляемых источников
Объявите типы в языке, совместимом с спецификацией CLS и скомпилируйте этот файл.
Экспортируйте сборку, содержащую типы, с помощью программы экспорта библиотеки типов (Tlbexp.exe).
Экспортированная библиотека COM-типов используется в качестве основы для объявления управляемых типов, ориентированных на COM.
Создание вызываемой оболочки времени выполнения
Считая, что имеется IDL-файл или файл библиотеки типов, решите, какие классы и интерфейсы необходимо включить в пользовательскую вызываемую оболочку времени выполнения. Можно исключить любые типы, которые не будут использоваться, непосредственно или косвенно, в приложении.
Создайте файл источника на языке, совместимом с CLS, и объявите типы. Полное описание процедуры преобразования при импорте см. в разделе Обзор преобразования библиотеки типов в сборку. Фактически, при создании настраиваемой вызываемой оболочки времени выполнения разработчик вручную выполняет все операции по преобразованию типов, предоставляемые программой импорта библиотеки типов (Tlbimp.exe). В примере, следующем этой процедуре, показаны типы в файле IDL или библиотеки типов и соответствующие типы в коде C#.
После завершения объявлений следует выполнить компиляцию этого файла так же, как и компиляцию любого другого управляемого исходного кода.
Как и в случае типов, импортированных с помощью программы Tlbimp.exe, для некоторых требуются дополнительные сведения, которые можно добавить непосредственно в разрабатываемый код. Подробности см. в разделе Практическое руководство. Редактирование сборок взаимодействия.
Пример
В следующем примере кода показан пример интерфейса ISATest и класса SATest в IDL вместе с соответствующими типами в исходном коде C#.
Файл IDL или библиотеки типов
[
object,
uuid(40A8C65D-2448-447A-B786-64682CBEF133),
dual,
helpstring("ISATest Interface"),
pointer_default(unique)
]
interface ISATest : IDispatch
{
[id(1), helpstring("method InSArray")]
HRESULT InSArray([in] SAFEARRAY(int) *ppsa, [out,retval] int *pSum);
};
[
uuid(116CCA1E-7E39-4515-9849-90790DA6431E),
helpstring("SATest Class")
]
coclass SATest
{
[default] interface ISATest;
};
Оболочка в управляемом исходном коде
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
[assembly:Guid("E4A992B8-6F5C-442C-96E7-C4778924C753")]
[assembly:ImportedFromTypeLib("SAServerLib")]
namespace SAServer
{
[ComImport]
[Guid("40A8C65D-2448-447A-B786-64682CBEF133")]
[TypeLibType(TypeLibTypeFlags.FLicensed)]
public interface ISATest
{
[DispId(1)]
//[MethodImpl(MethodImplOptions.InternalCall,
// MethodCodeType=MethodCodeType.Runtime)]
int InSArray( [MarshalAs(UnmanagedType.SafeArray,
SafeArraySubType=VarEnum.VT_I4)] ref int[] param );
}
[ComImport]
[Guid("116CCA1E-7E39-4515-9849-90790DA6431E")]
[ClassInterface(ClassInterfaceType.None)]
[TypeLibType(TypeLibTypeFlags.FCanCreate)]
public class SATest : ISATest
{
[DispId(1)]
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType=MethodCodeType.Runtime)]
extern int ISATest.InSArray( [MarshalAs(UnmanagedType.SafeArray,
SafeArraySubType=VarEnum.VT_I4)] ref int[] param );
}
}
См. также
Задачи
Практическое руководство. Редактирование сборок взаимодействия
Ссылки
Tlbimp.exe (программа экспорта библиотек типов)
Tlbexp.exe (программа экспорта библиотек типов)
Основные понятия
Настройка вызываемых оболочек времени выполнения