gpt4 book ai didi

.net - 为什么不能通过 .NET 中的 COM 使用 .NET COM 库?

转载 作者:行者123 更新时间:2023-12-03 21:25:50 27 4
gpt4 key购买 nike

现在,我知道如果库在 .NET 中,通过 COM 访问它有点毫无意义,但是,我有点困惑,因为如果我要让某人编写一个库并通过 COM 公开它,那人们应该可以使用任何语言自由地这样做。

对我来说,COM 库是用哪种语言编写的并不重要,那么为什么重要呢?

作为引用,当您对从 .NET 库生成的 .tlb 文件使用 tlbimp 时会发生以下情况:

C:\dev>tlbimp test.tlb
Microsoft (R) .NET Framework Type Library to Assembly Converter 4.0.30319.1
Copyright (C) Microsoft Corporation. All rights reserved.

TlbImp : error TI1029 : Type library 'test' was exported from
a CLR assembly and cannot be re-imported as a CLR assembly.

此外,我的测试 COM 库使用 IUnknown,仅支持早期绑定(bind) COM 互操作。

最佳答案

tlbimp 只是问题的开始。

每个 COM 可见的 .NET 对象都实现 IManagedObject。每次尝试通过 COM 接口(interface)调用对象时,.NET 都会为 IManagedObject 执行 QueryInterface,如果成功,对象将被解包并直接访问。以这种方式消除互操作调用被认为是一种性能优化。

这在基于 COM 的互操作方案中是一个严重的问题,其中多个组件可以用 .NET 语言实现。如果每个 .NET 组件实现其自己的 tlbimp 生成的 COM 接口(interface)版本,它们将无法使用该接口(interface)相互通信。即使接口(interface)的每个 tlbimp 副本具有相同的 COM GUID,.NET 仍将它们视为单独的接口(interface)。这个问题的“正确”解决方案是在主互操作程序集中定义 COM 接口(interface),并让每个 .NET 实现的组件使用相同的接口(interface)副本,但如果组件开发人员之间没有协调,这不太可能发生。

微软开发人员曾在 http://blogs.msdn.com/b/jmstall/archive/2009/07/09/icustomqueryinterface-and-clr-v4.aspx 上强调过此问题。以及 .NET 4 的解决方案,但它基于预发布版本,在最终版本中不起作用。我不知道微软在其他任何地方都承认它。

一种解决方案是放弃 .NET-to-.NET 场景中的接口(interface),而改用反射。这可能在许多情况下都有效,但性能当然不是很好。可能最好的解决方案是使用非托管代码来聚合每个托管组件并拒绝对 IManagedObject 的 QueryInterface 尝试。这类似于上述博客条目中的描述,但不依赖于不再像该博客中描述的那样工作的 .NET 功能。

IMO 的 .NET 互操作行为非常糟糕,并且明显违反了 COM 规则(相同的 IID == 相同的接口(interface),并且不必关心对象是用什么语言实现的)。但是 .NET 从一开始就是这样,开发人员对此行为的反馈并没有改变 .NET 团队中任何人的想法。

关于.net - 为什么不能通过 .NET 中的 COM 使用 .NET COM 库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15014266/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com