可以“枚举"吗?用于COM中的标志? [英] Can an "enum" be used for flags in COM?

查看:83
本文介绍了可以“枚举"吗?用于COM中的标志?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In the IDL for a COM object I do the following:

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

并具有可以将标志的总和(或按位或,相同的东西)的函数,例如(在IDL中)

and have functions that can take the sum (or bitwise-OR, same thing) of flags, e.g. (in IDL)

HRESULT _stdcall a_method([in] enum TxMyFlags);

,其预期用途的示例为:

with an example of intended usage being:

a_method( flagExtra | flagMoreOption );

这似乎可行,但实际上是允许的,还是可能是RPC传输或任何拒绝拒绝枚举定义中不完全包含的枚举参数值的东西?

It seems to work but is this actually permitted, or is it possible that the RPC transport or whatever would reject values of an enum parameter that are not exactly in the enum definition?

推荐答案

如果您的客户端和服务器正在运行(并且没有发生真正的混搭,也没有涉及RPC),那么您将不会发现任何问题,例如枚举.您定义的值,将被视为其int/long/大小等价的整数类型.

If your client and server are in process (and there is no real mashaling happening, no RPC involved), you will not see any problem as the enum, however you define it, will be treated as its int/long/whatever integral type equivalent in size.

因此,可能是进程外(或跨公寓封送)案件.在这种情况下,如此处的文档所述:枚举属性(并在您的评论中):

So it's the out-of-process (or cross apartment marshaling) case that maybe an issue. In this case, as stated in the doc here: enum attribute (and in your comments):

类型为enum的对象是int类型,其大小为与系统有关.默认情况下,枚举类型的对象被视为通过网络传输时,unsigned short类型的16位对象.超出范围0到32,767的值会导致运行时异常RPC_X_ENUM_VALUE_OUT_OF_RANGE.要将对象作为32位实体传输,将[v1_enum]属性应用于枚举typedef.

Objects of type enum are int types, and their size is system-dependent. By default, objects of enum types are treated as 16-bit objects of type unsigned short when transmitted over a network. Values outside the range 0 - 32,767 cause the run-time exception RPC_X_ENUM_VALUE_OUT_OF_RANGE. To transmit objects as 32-bit entities, apply the [v1_enum] attribute to the enum typedef.

因此,您基本上有两种选择可以在idl中使用枚举:1)使用不带 typedef enum 和2)将 enum typedef 并添加 v1_enum 属性.在第一种情况下,只需在网络上根据需要在方法中声明类型,在第二种情况下,则必须使用该类型(因此为v1_enum属性):

So you basically have two options to use enums in idl: 1) use enum without typedef and 2) use enum with typedef and add the v1_enum attribute. In the first case, you can just declare the type in the method as you want on the wire, in the second, you will have to use that type (hence the v1_enum attribute):

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);

如果您声明这样的方法:

If you declare a method like this:

 HRESULT MyMethod1(enum MY_ENUM myParam);

然后,您将使用16位枚举(并且您不能在未输入typedef的枚举上添加v1_enum),这样不好(除非您可以接受0-32767的限制).

Then you will use a 16-bit enum (and you can't add v1_enum on a not-typedef'd enum), so that's not good (unless you're ok with the 0-32767 limit).

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

Note I also declared this to ease typedef enum as flags conversion in the second line:

MY_ENUM_TYPE operator | (MY_ENUM_TYPE l, MY_ENUM_TYPE r) { return (MY_ENUM_TYPE)((int)l | (int)r); }

好吧.typedef方式对我来说似乎有点过大,但它具有被键入的优势.如果您在Windows SDK中扫描Microsof自己的.IDL文件,您会发现它们基本上同时使用了这两个文件.

Well. The typedef way seems a bit overkill to me, but it has the advantage of being typed. If you scan Microsof's own .IDL files in the Windows SDK, you'll see they basically use both...

这篇关于可以“枚举"吗?用于COM中的标志?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆