2009-04-23 65 views
1

我有一个COM服务器的方法目前返回一个整数:如何在COM服务器中使用用户定义类型(UDT)?

[ 
    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")]; 
+0

你可以试试`enum AA {}; HRESULT MyQuery([out,retval]枚举AA *)`我记得midl具有非常'C'的行为(没有自动typedefs)。 – Ismael 2009-04-23 20:32:47

+0

您正在使用哪种编译器? – 2009-04-23 23:19:47

+0

@John Dibling:Visual Studio 2005(出于某种原因,我还没有完全升级到2008)。 – Mat 2009-04-24 18:43:32

回答

1

(这是改编自一个真实IDL,所以我知道它的工作原理)

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

此外,在图书馆部分,您必须包括枚举为好,或枚举不会被导出到类型库:

library MyLib 
{ 
    enum MyEnum; 
... 
}; 
1

这是非常编译器的依赖,因为枚举没有一个固定的存储容量。

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

1

你已经差不多了,但是idl编译器比cl.exe有更严格的语法。你需要像这样在枚举之前有最初的枚举名。

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

如果你建立并注册您的TLB那么脚本语言应该能够访问你的枚举脚本和.NET。

相关问题