在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传输或其他什么可能会拒绝枚举参数中不完全在枚举定义中的值?
答案 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)使用enum
和typedef
并添加{{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文件,您会看到他们基本上都使用这两个...