【问题标题】:VB.NET class gets assembly name prepended to name in COM?VB.NET 类在 COM 中获取程序集名称前面的名称?
【发布时间】:2020-02-08 02:39:51
【问题描述】:

我有一个 .NET COM 程序集 A 由 3 个类组成,例如 BCD。我曾经将我的 VB6 中的这个 COM dll 称为 A.BA.CA.D

最近尝试重新编译我的 VB6 项目时,我仍然可以引用 A.BA.C

但是 D 类在 VB6 对象浏览器中被公开为 A.A_D。我的问题是为什么类名和下划线被附加到类D

我正在为 DLL 使用 .NET 框架 4.0。在下面找到伪代码供您参考。不使用 ProgID。相反,在 VB6 中使用对对象的直接引用。

A 类:配置为类库

B类:

<ComClass(B.ClassId, B.InterfaceId, B.EventsId), ComVisible(True)> Public Class B

#Region "COM GUIDs"
    'All the real GUIDs/Interface/Events are replaced with zeros for code security purpose
    Public Const ClassId As String = "0000000-0000-0000-0000-000000000000"
    Public Const InterfaceId As String = "00000000-0000-0000-0000-000000000000"
    Public Const EventsId As String = "00000000-0000-0000-0000-000000000000"
#End Region

C类:

<ComClass(C.ClassId, C.InterfaceId, C.EventsId), ComVisible(True)> Public Class C

#Region "COM GUIDs"
    'All the real GUIDs/Interface/Events are replaced with zeros for code security purpose
    Public Const ClassId As String = "0000000-0000-0000-0000-000000000000"
    Public Const InterfaceId As String = "00000000-0000-0000-0000-000000000000"
    Public Const EventsId As String = "00000000-0000-0000-0000-000000000000"
#End Region

D 类:

<ComClass(D.ClassId, D.InterfaceId, D.EventsId), ComVisible(True)> Public Class D

#Region "GUIDs"
    'All the real GUIDs are replaced with zeros
    Friend Const ClassId As String = "00000000-0000-0000-0000-000000000000"
    Friend Const InterfaceId As String = "00000000-0000-0000-0000-000000000000"
    Friend Const EventsId As String = "00000000-0000-0000-0000-000000000000"
#End Region

在 OLEView 中,D 类单独被命名空间 A 前置。B 类和 C 类保持不变。当我回溯这个 DLL 时,命名空间只有在迁移到 Framework 4 后才会被前置。这个问题似乎与prepending-namespace-to-typelib-coclass-name 中提到的问题相似 但这里的区别是我还在使用 Visual Studio 2010 并且我没有找到

嵌入互操作类型属性

OLEView.exe 输出

coclass D

[uuid(00000000-0000-0000-0000-000000000000),
version(1.0),
custom({00000000-0000-0000-0000-000000000000}, "A.D")]

coclass A_D {
    interface _Object;
    [default] interface _D;
    [default, source] dispinterface __D;
};

coclass B

[uuid(00000000-0000-0000-0000-000000000000),
version(1.0),
custom({00000000-0000-0000-0000-000000000000}, "A.B")]

coclass B{
   interface _Object;
   [default] interface _B;
   [default, source] dispinterface __B;
};

【问题讨论】:

  • 很难说没有任何代码
  • 您没有显示任何代码。您是否在类中使用 [ProgId] 属性?

标签: .net dll com vb6 com-interop


【解决方案1】:

如果没有看到D 的真实类名,就无法确定。但一个可能的可能性是裸名称 D 会与其他名称冲突,因此编译器 (*) 添加程序集名称以区分它。

如果您想确认这一点,您可以在 OLEView 或类似工具中为您的程序集加载 .TLB 文件并检查 IDL,这可能会显示相同的 A_D 名称。

另一个测试是将D 更改为几乎任何其他内容,然后重新编译,看看是否有任何效果。

如评论中所述,使用 [ProgId] 属性可能是一种强制它在类型库中提供更理想名称的方法。

(* 不是真正的编译器,而是生成 COM 包装层和类型库的工具)

【讨论】:

  • 当我尝试在 Excel VBA 中获取参考时,正如您所说,类名显示为 A.A_D。但在 ildasm.exe 工具中它只是显示为 A.D
  • ildasm 向您显示 .NET 名称 - 而不是呈现给 COM 的名称
  • Ref: stackoverflow.com/questions/3940498/… 您可以使用像 OLEView 或 github.com/tyranid/oleviewdotnet/releases 这样的工具作为替代。您要检查的文件类似于 D.TLB(TLB 表示“类型库”)
  • 您好 UuDdLrLrSs,在我的查询中包含 OLEView 输出。在 Stackoverflow 中也发现了类似的问题。但无法在 VS2010 中找到该解决方案。谢谢
  • 这是有道理的。我发现生成 COM 接口的 .NET 工具有些僵化,不允许进行太多自定义。很难说“为什么”他们选择这样做而不是其他方法或让你有更多的控制权。如果您将枚举从 C# 导出到 VB6,它们在命名方面会遇到类似的问题。
猜你喜欢
  • 2011-05-15
  • 2019-01-29
  • 2010-11-24
  • 2011-02-06
  • 1970-01-01
  • 2011-09-09
  • 1970-01-01
  • 2015-02-02
  • 1970-01-01
相关资源
最近更新 更多