Можно ли выставить С# 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 будет допустимым в перечислении.