【问题标题】:Problem creating COM-library only containing enum's创建仅包含枚举的 COM 库的问题
【发布时间】:2011-09-28 13:29:33
【问题描述】:

我正在做一个 COM 互操作项目。用 C# 和 .NET Interop 替换一些 VB 和 C++ ATL COM 项目。当我在 .NET 中定义枚举并将它们设为 ComVisible 时,它​​们会暴露为 Typelib.EnumType_EnumValue 而不仅仅是 Typelib.EnumValue。 typelib 导出器这样做是为了确保值名称是唯一的。但我知道我所有的枚举都是独一无二的,所以我不想要下划线。如果我不去掉下划线,还有很多客户端代码需要修改。

为了找到解决这个问题的方法,我在一个 IDL 文件中定义了枚举,并由此创建了一个 typelib 和 .Net 互操作。

[
  uuid(64893FD4-359D-46B9-BC1E-48C055796104),
  version(1.0),
  helpstring("ABC"),
  helpfile("AAA.chm"),
  helpcontext(0x00000001)
]

library EnumTypeLib
{
    importlib("stdole2.tlb");
    typedef [uuid(8FF85069-C4E2-4540-A277-4C0F3C19B807), helpstring("MyEnum"), helpcontext(0x00000066)]
    enum MyEnum {
        Value1 = 0,
        Value2 = 1,
    } MyEnum;
};

我使用 MIDL.exe 创建了一个类型库,它会生成一个 tlb 文件。

我使用 tlbimp.exe 创建了一个程序集。使用与其他互操作程序集相同的密钥对程序集进行签名。

tlbimp OpenStructureAdapterEnum.tlb /keyfile:KeyFile.snk

然后我用 regasm.exe 注册程序集 这个程序集看起来很好,并且包含没有下划线的枚举。但问题是无法从 OLE/COM 对象查看器或 VBA 或 VB6 中看到 COM 库。当我从另一个暴露 COM 的程序集中引用枚举时,包含对枚举的引用的接口部分将被暴露为受限方法。

[restricted] void Missing7();
[restricted] void Missing8();
[restricted] void Missing9();
[restricted] void Missing10();

如何创建一个只包含枚举(没有下划线)并从其他 .net 互操作程序集引用这些的 COM 库?

【问题讨论】:

    标签: .net com interop com-interop idl


    【解决方案1】:

    先回答你的最后一个问题。您想要的是 TypeLib 而不是 COM 库。 COM 接口是一堆代码和函数指针,TypeLib 是用于与这些指针交互的映射(以及定义和枚举以及一堆其他东西)。只有当它们结合在一起时,才会有一个 COM 库。因为没有 COM 接口,所以不能有 COM 库。

    Microsoft 提供了一个关于如何create a TypeLib without an interface 的示例。它与您描述的非常相似。您会注意到,其中没有 COM 接口。也正因为如此,它必须保持一个低级的 TypeLib。

    下一个问题是 .NET 程序集。当您使用TlbImp.exe 将枚举导入代码时,您可以在代码中使用这些枚举 - 在程序集中。这是您可以对枚举执行的操作的限制。您无法导出这些枚举,因为它们不属于您的 .NET 代码。枚举归 TypeLib 所有。您的 .NET 代码有权使用该枚举,但它不能声称拥有该枚举。

    最后,回答你的第一个问题。您需要使用 .NET 提供的功能。它能够定义枚举并导出它们并使它们在 COM 中可见。虽然我理解对命名约定的挫败感,但这不是您应该尝试解决或绕过的问题。如您所见,试图绕过命名约定的这个小问题会导致重大问题,实际上使您的新代码无法使用。

    【讨论】:

      【解决方案2】:

      我已经这样做了:

      在 .NET 中,我创建了一个名为 PermissionControlLib 的 COM 可见库,其枚举如下:

      public enum NetOperations
      {
         Oper1,
         Oper2,
         Oper3
      }
      

      在 VB6 中,我创建了另一个这样的枚举:

      Public Enum VBOperations
         Oper1=NetOperations.NetOperations_Oper1,
         Oper2=NetOperations.NetOperations_Oper2,
         Oper3=NetOperations.NetOperations_Oper3
      End Enum
      

      用法:

      Dim ud as PermissionControlLib.IUser
      Set ud = New User
      Dim b as Boolean
      b = ud.HasPermissionInOperation(VbOperations.Oper1)
      

      【讨论】:

      • 您可能只能在 VB6 中在自己的 DLL 中创建枚举,然后将该 DLL 导入到 .NET 项目中。我认为这也可以,但工作量会少一些,而且可能会更不容易出错。
      猜你喜欢
      • 2021-06-06
      • 1970-01-01
      • 2021-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-24
      • 2010-12-11
      • 1970-01-01
      相关资源
      最近更新 更多