3

我正在做一个 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 Interop 程序集中引用这些的 COM 库?

4

2 回答 2

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)
于 2013-10-14T14:52:28.100 回答
2

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

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

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

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

于 2011-08-06T08:39:11.597 回答