如何在COM服务器中使用用户定义类型(UDT)?

时间:2009-04-23 19:47:22

标签: c++ com enums

我有一个COM服务器,其方法当前返回一个整数:

[
    object,
    uuid("..."),
    dual,
    helpstring("IMyCOMServer Interface"),
    pointer_default(unique)
]
__interface IMyCOMServer : IDispatch
{
    [id(1), helpstring("method MyQuery")]
    HRESULT MyQuery([in] BSTR instr, [out,retval] int* outint);
};

这编译很好,但我宁愿返回一个枚举:(此代码实际上在接口定义之上)

typedef
[
    uuid("..."),
    v1_enum,
    helpstring("Enum")
]
enum {
    value_a,
    value_b,
    value_c
} MyEnum;

它再次编译自己的权利,但是一旦我在接口和实现中将int*更改为MyEnum*,我就会遇到链接器错误:

[id(1), helpstring("method MyQuery")]
HRESULT MyQuery([in] BSTR instr, [out,retval] MyEnum* outint);

error MIDL2025 : syntax error : expecting a type specification near "MyEnum"

无论我采用哪种方式,我都无法进行编译。


感谢Euro Micelli,事实证明真正的问题是我的用户定义类型(枚举)没有进入生成的.IDL文件。通过在线论坛查询判断,这似乎是一个常见问题。

博客文章Star Tech: UDT (User Defined Types) and COM引导我走正确的道路。使用属性ATL时似乎需要一种解决方法。

总之,我做了以下更改:

创建udt.idl

import "oaidl.idl";
import "ocidl.idl";

[
    uuid("..."),
    v1_enum,
    helpstring("Enum")
]
typedef enum MyEnum {
    value_a,
    value_b,
    value_c
} MyEnum_t;

[
    version(1.0),
    uuid(...),
    helpstring(...)
]
library MyLibrary
{
    enum MyEnum;
}

在主.cpp文件中的模块属性之前添加了以下行,以便将上述IDL导入到生成的文件中:

[importidl("udt.idl")];

3 个答案:

答案 0 :(得分:1)

这是依赖于编译器的,因为枚举没有固定的存储大小。

还有兼容性角度 - 你会如何在Visual Basic或C#中表示枚举?底层存储就像一个整数,所以这就是COM允许的。

答案 1 :(得分:1)

你几乎得到了它,但idl编译器的语法比cl.exe更严格。你需要在枚举之前有这样的初始枚举名称。

typedef
[uuid("..."), v1_enum, helpstring("Enum")]
enum tagMyEnum
{
    value_a,
    value_b,
    value_c
} MyEnum;

如果您构建并注册了tlb,那么脚本语言应该能够以脚本和.NET访问您的枚举。

答案 2 :(得分:1)

(这是根据实际的IDL改编的,所以我知道它有效)

[uuid(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX), v1_enum, helpstring("Enum")]
enum MyEnum {
    value_a,
    value_b,
    value_c
} ;

另外,在“库”部分中,您还必须包含枚举,否则枚举将不会导出到类型库中:

library MyLib
{
    enum MyEnum;
...
};