问题描述
我正在开发一种通过 COM 互操作公开一些 .NET API 的产品.作为构建的一部分,我们为所有此类程序集生成 *.tlb 文件,并将它们作为单独 SDK 包的一部分提供.我们的客户可以在我们的产品上安装 SDK 并创建使用我们的 COM API 的应用程序.
I'm working on a product that exposes some .NET API through COM interop. As a part of the build we generate *.tlb files for all such assemblies and deliver them as a part of a separate SDK package. Our customers can install the SDK on top of our product and create applications that use our COM API.
我们是否需要向产品本身发送和注册这些 *.tlb 文件?是否存在在运行时需要 *.tlb 时执行针对它们编码的第三方库的情况?
Do we need to ship and register those *.tlb files with the product itself? Is there a situation when *.tlb are required at runtime, when third-party libraries coded against them are executed?
如果您回答是",请说明它是如何工作的.我在互联网上看到很多评论说我必须交付并注册它们,但我没有找到一个清楚地解释为什么应该这样做的评论.这让我怀疑这是真的.
Please explain how it works, if you answer Yes. I seen a lot of comments all over the internet that say that I have to deliver and register them, but I did not find one that clearly explains why it should be done. That made me doubt that it is true.
推荐答案
是的,这是可能的.特别是在 .NET 的情况下,您不应忽略注册类型库,因为您无法预测客户端代码将如何使用您的服务器.
Yes, that's possible. Especially in the case of .NET, you should not omit registering the type library because you cannot predict how the client code is going to use your server.
它们不是特别常见,但有两种情况:
They are not particularly common but there are two cases:
当客户端代码调用您的 [ComVisible] 方法并且调用跨越公寓边界时.公寓是一个有点模糊的 COM 概念,您必须了解 STA 和 MTA 线程之间的区别.保持简单:当从另一个线程、另一个进程或另一台机器进行调用时,通常会跨越单元边界.COM 需要帮助来确定如何将调用的参数序列化为 IPC 数据包,这需要知道参数的类型.COM 中没有反射的概念,因此不能轻易地自动完成.需要一个单独的 DLL 来实现代理和存根,几乎总是从 IDL 文件生成.这在 .NET 中很难实现,您几乎总是使用方便的第二种方式,即使用 Windows 中内置的标准编组器.它使用类型库来找出参数类型是什么.Regasm.exe/tlb 选项确保接口代理/存根和类型库已注册,以便标准编组器可以找到该库.
When the client code calls your [ComVisible] method and the call crosses an apartment boundary. Apartments are a COM concept that is a bit fuzzy, you have to understand the difference between STA and MTA threads. Keeping it simple: an apartment boundary is typically crossed when the call is made from another thread, from another process or from another machine. COM needs help to figure out how to serialize the arguments of the call into a IPC packet and that requires knowing the type of the arguments. There is no concept of Reflection in COM so it cannot easily be done automatically. A separate DLL is required that implements the proxy and the stub, almost always generated from an IDL file. That's hard to come by in .NET, you almost always use the convenient second way, using the standard marshaller built into Windows. Which uses a type library to find out what the argument types are. The Regasm.exe /tlb option ensures that the interface proxy/stub and type library is registered so the standard marshaller can find the library.
当您在公共接口中公开一个结构时.结构在互操作场景中非常麻烦,它们的布局高度依赖于编译器设置.等效的 .NET 属性是 StructLayout.Pack.在 .NET 中固定为 8,但客户端代码不知道这一点.要访问结构,客户端代码必须使用 IRecordInfo.这让它可以找出结构的每个字段在内存中的位置.类型库提供了 IRecordInfo 需要的信息.最好完全避免在 .NET 中轻松完成结构.
When you expose a struct in your public interface. Structs are very troublesome in interop scenarios, they have a layout that's highly dependent on compiler settings. The equivalent .NET property is StructLayout.Pack. Fixed at 8 in .NET but the client code doesn't know that. To access a struct, the client code must use IRecordInfo. Which lets it find out where every field of the struct is located in memory. A type library provides the info that IRecordInfo needs. It is certainly best to avoid structs entirely and very easily done in .NET.
这篇关于*.tlb 文件是否曾在运行时使用过?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!