COM中的标志可以使用“枚举”吗?

时间:2014-07-28 21:56:59

标签: com enums idl midl

在COM对象的IDL中,我执行以下操作:

enum TxMyFlags
{
,    flagOption = 1,
,    flagOtherOption = 2,
,    flagMoreOption = 4,
,    flagAnotherFlag = 8,
,    flagExtra = 128
// etc.
};

并且具有可以采用标志的和(或按位或相同的)标记的函数,例如(在IDL中)

HRESULT _stdcall a_method([in] enum TxMyFlags);

以预期用法为例:

a_method( flagExtra | flagMoreOption );

它似乎工作但实际上是允许的,或者RPC传输或其他什么可能会拒绝枚举参数中不完全在枚举定义中的值?

1 个答案:

答案 0 :(得分:4)

如果您的客户端和服务器正在进行中(并且没有真正的mashaling发生,不涉及RPC),您将看不到任何问题,因为枚举,无论您定义它,将被视为其int / long / whatever整数类型相当于。

因此,这可能是一个问题,即进程外(或跨公寓编组)案例。在这种情况下,如此处的文档中所述:enum attribute(以及您的评论中):

  

enum类型的对象是int类型,它们的大小是   取决于系统。默认情况下,枚举类型的对象被视为   通过网络传输时,无符号短类型的16位对象。   超出0 - 32,767范围的值会导致运行时异常   RPC_X_ENUM_VALUE_OUT_OF_RANGE。要将对象作为32位实体传输,   将[v1_enum]属性应用于枚举typedef。

所以你基本上有两个选项可以在idl中使用枚举:1)使用enum而不使用typedef和2)使用enumtypedef并添加{{1属性。在第一种情况下,您可以根据需要在线路上声明方法中的类型,在第二种情况下,您将必须使用该类型(因此v1_enum属性):

v1_enum

像这样使用:

enum MY_ENUM
{
    MY_ENUM_FIRST = 1,
    MY_ENUM_SECOND = 2,
};

typedef [v1_enum] enum
{
    MY_ENUM_TYPE_FIRST = 1,
    MY_ENUM_TYPE_SECOND = 2
} MY_ENUM_TYPE;

[object, uuid(15A7560E-901B-44D2-B841-58620B1A76C5)]
interface IMyInterface : IUnknown
{
    HRESULT MyMethod1(int myParam);
    HRESULT MyMethod2(MY_ENUM_TYPE myParam);
};

如果您声明一个这样的方法:

IMyInterface *p = ...;
p->MyMethod1(MY_ENUM_FIRST | MY_ENUM_SECOND);
p->MyMethod2(MY_ENUM_TYPE::MY_ENUM_TYPE_FIRST | MY_ENUM_TYPE::MY_ENUM_TYPE_SECOND);

然后你将使用16位枚举(并且你不能在非类型定义的枚举上添加v1_enum),所以这不好(除非你没有0-32767限制)。

注意我还声明这可以简化typedef枚举作为第二行中的标志转换:

 HRESULT MyMethod1(enum MY_ENUM myParam);

好。 typedef方式对我来说似乎有点矫枉过正,但它具有被打字的优点。如果您在Windows SDK中扫描Microsof自己的.IDL文件,您会看到他们基本上都使用这两个...