我有一个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")];
答案 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;
...
};