Можно ли выставить C# Enum для вызывающих абонентов COM Interop, и если да, то как?
У меня есть управляемая сборка, которая вызывается через COM Interop. Как клиент VBScript, клиент Perl и так далее.
Классы украшены
[ClassInterface(ClassInterfaceType.AutoDual)]
[GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000E")]
[ComVisible(true)]
Затем, конечно, я делаю регазму, и все методы работают просто отлично.
Но в сборке также есть типы enum. Я хотел бы использовать символические имена приложений COM, для значений перечисления.
Как выставить перечисления через COM-взаимодействие? Мне просто нужно добавить эти атрибуты?
[GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000E")]
[ComVisible(true)]
И как мне ссылаться на эти символические имена в VBScript? Я не вижу типы перечисления в OleView. (Должен ли я?) Я вижу все другие типы в OleView.
3 ответа
VBScript и другие клиенты с поздним связыванием используют IDispatch для вызова методов на объектах. Таким образом, эти языки не имеют доступа к информации о типах в библиотеке типов - они просто создают объект по GUID, возвращают указатель IDispatch и начинают вызывать методы по имени.
Я не уверен в части вопроса о взаимодействии COM, но даже если перечисления действительно отображаются в OleView, вы не сможете использовать их напрямую.
Однако, если вы можете публиковать перечисления в библиотеке типов, я написал инструмент несколько лет назад, который может генерировать файл сценария (vbs или js), содержащий все перечисления из библиотеки типов в качестве констант.
Смотрите здесь: http://www.kontrollbehov.com/tools/tlb2const/
Моя (пока что только) сборка.NET, которую я сделал COM-видимой, также имела тип enum, который прекрасно отображался в OleView. У меня была вся библиотека, видимая COM, так
[ComVisible(true)]
не было необходимости. Ваш тип enum общедоступен?
Одна вещь, которая произошла, состояла в том, что различным перечислениям предшествовал префикс enum type name:
public enum DataType
{
INT32,
FLOAT64,
INT8
}
превратился в:
typedef [...]
enum {
DataType_INT32 = 0,
DataType_FLOAT64 = 1,
DataType_INT8 = 2
} DataType;
в библиотеке типов.
Я знаю, что это очень старая тема, но я добавлю свои 2 цента для будущих исследователей. Когда я определяю перечисление в C#, я украшаю его с помощью [Guid(...), ComVisible(true)], а не GuidAttribute.
Например:
[Guid("28637488-C6B3-44b6-8621-867441284B51"), ComVisible(true)]
public enum myEnum
{
first,
second,
third,
fourth
}
Тогда перечисление будет доступно в VB6 как myEnum_first, myEnum_second и так далее.
Вы также можете включить присвоение значений ключей в этот список, так что first = 1 будет допустимым в перечислении.