Можно ли выставить С# Enum для вызовов COM Interop, и если да, то как?

У меня есть управляемая сборка, которая вызывается через COM Interop. Как клиент VBScript, клиент Perl и т.д.

Классы украшены

[ClassInterface(ClassInterfaceType.AutoDual)]
[GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000E")]
[ComVisible(true)]

Тогда, конечно же, я делаю регаз, и все методы работают нормально.

Но в сборке есть также перечисляемые типы. Я хотел бы использовать символические имена COM-приложений для значений enum.

Как я могу просмотреть перечисления через COM-взаимодействие? Нужно ли просто добавлять эти атрибуты?

[GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000E")]
[ComVisible(true)]

А потом, как я могу ссылаться на эти символические имена в VBScript? Я не вижу типы перечислений в OleView. (Должен ли я?) Я вижу все другие типы в OleView.

Ответ 1

VBScript и другие поздние клиенты используют IDispatch для вызова методов на объектах. Таким образом, эти языки не имеют доступа к информации о типе в typelib - они просто создают объект из GUID, возвращают указатель IDispatch и начинают вызывать методы по имени.

Я не уверен в части ответа на COM-вопрос, но даже если перечисления отображались в OleView, вы не сможете использовать их напрямую.

Однако, если вы можете публиковать перечисления в typelib, я написал инструмент назад, который может сгенерировать файл script (vbs или js), содержащий все перечисления из typelib в качестве констант.

Смотрите здесь: http://www.kontrollbehov.com/tools/tlb2const/

Ответ 2

Моя (пока только) сборка .NET, которую я сделал COM-видимой, также имела тип перечисления, который в OleView проявился просто отлично. У меня была полная видимость всей библиотеки, поэтому

[ComVisible(true)]

не требовалось. Является ли ваш тип перечисления общедоступным?

Одна вещь, которая произошла, заключалась в том, что разные перечисления были "префикс" с именем "enum type name" _:

public enum DataType
{
    INT32,
    FLOAT64,
    INT8
}

превратился в:

typedef [...]
enum {
    DataType_INT32 = 0,
    DataType_FLOAT64 = 1,
    DataType_INT8 = 2
} DataType;

в библиотеке типов.

Ответ 3

Я знаю, что это очень старая тема, но я добавлю свои 2 цента для будущих исследователей. Когда я определяю перечисление в С#, я украшаю его с помощью [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 будет допустимым в перечислении.