如何在COM对象中声明typdef

How to declare a typdef in COM object idl?

本文关键字:声明 typdef 对象 COM      更新时间:2023-10-16

我有一个用c++写的COM对象,我试图为一个简单类型(如int/bool)的序列声明一个类型定义,并访问它,以便在c#中创建其类型的变量,在那里我添加了对这个COM对象的引用。在我在这里添加的代码中,我写了两个选项,我试图声明typdef -但没有一个是为我工作-我不能在我的c#类中初始化这种类型的参数。这是我的idl的相关部分(库):

 [
    uuid(0EA0AD9B-9314-4480-8C69-22719C2EA9CF),
    version(1.0),]
library ATLProject9Lib
{
    typedef [public,uuid(9d286340-62c4-11e6-8b77-86f30ca893d3)]
    int aaa;
    typedef [public]
    double numberToAdd;

    struct BarStruct;
    importlib("stdole2.tlb");
    [
        uuid(172B34D8-5D19-4635-B4AD-9171F522CA0A)      
    ]
    dispinterface _IScheduleEvents
    {
    properties:
    methods:
    };
    [
        uuid(34413E93-0916-4773-99C4-79163A44E4A0)      
    ]
    coclass Schedule
    {
        [default] interface ISchedule;
        [default, source] dispinterface _IScheduleEvents;
    };
};
第二个问题:声明int类型的typdef序列,例如:
typedef [public,uuid(9d286340-62c4-11e6-8b77-86f30ca893d3)]
sequence<int> aaa;
typedef [public]
double numberToAdd;

此代码未编译。我得到以下错误:

1>.ATLProject9.idl(47): error MIDL2025: syntax error : expecting a declarator or * near "<"
1>.ATLProject9.idl(47): error MIDL2025: syntax error : expecting ; or , near "<"
1>.ATLProject9.idl(47): error MIDL2026: cannot recover from earlier syntax errors; aborting compilation

在COM对象中声明类型定义(对于简单类型和序列)的正确方法是什么?

你想做的事情很少有意义。typedef声明一个类型别名,只是类型的另一个名称。它不声明变量,在c++中也是如此。类型别名也不能在Tlbimp中存活下来,Tlbimp是编写c#代码所需的类型库导入器,类型标识在CLR中是一个非常重要的问题,而且它没有使用两个名称来引用相同类型的机制。因此,类型库导入器总是将typedef反编译为其原始名称。

在IDL中不能声明变量。COM使用非常严格的基于接口的编程范例,完全隐藏了类型的实现。对于可以在任意语言实现之间工作的互操作代码来说,它是好的最终原因。变量有太多的包袱,不同的语言实现对变量的存储地址和对齐方式有不同的选择。

泛型或模板也不可能,没有人同意如何实现这样的特性。或者根本不实现它。. net泛型与c++模板有很大的不同。

这些限制是有意为之的。暴露在c++代码中声明的变量的唯一方法是编写带有属性getter的接口。

查看MIDL参考文档。显然没有sequence关键字。这表明:

 typedef struct {
    int     foo;
 } IntStruct;
 typedef struct {
    int     cMax;
    [size_is(cMax)] IntStruct values[];
 } ListOfInts;

 typedef struct {
    int     foo;
 } IntStruct;
 typedef struct {
    int     cMax;
    [size_is(cMax)] IntStruct* values;
 } ListOfInts;

您真的需要命名为aaanumberToAdd的类型吗?