在 C# 中使用 COM dll
我们有 COM dll,它是用 C++ 编写的,并且已被用 vb 6.0 编写的应用程序使用。我的公司计划在.Net 平台上编写新版本的应用程序。
就性能而言,当在 C# 项目中使用 COM dll 时,我应该从下面列出的 3 个选项中选择什么?
- 只需将 dll 添加为 com 引用
- 使用 C++/Cli 编写包装器 dll
- 使用 TlbImp 生成包装器 dll .exe
或者还有其他选项吗?
谢谢。
We have COM dll which was written in C++ and has been used by the apps written in vb 6.0. My company plans write the newer versions of apps in .Net platform.
As far as the performance is concerned, when using a COM dll in a C# project, what should I choose from the 3 options listed below
- Just adding the dll as a com reference
- Writing a wrapper dll with C++/Cli
- Generating a wrapper dll using TlbImp.exe
Or are there any other options?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
用 C++/CLI 编写包装器并不会更快,CLR 中的 COM 互操作编组器已进行了大量优化。它会从您在添加对 COM 服务器的引用时创建的互操作库自动生成机器代码存根。 A 还做了很多与异常相关的工作,这些工作是非常不可见且很难自己完成的。
它确保故障 HRESULT 正确转换为托管异常,并且托管异常不会泄漏到 COM 服务器代码中。当你这样做时,你会产生“加快速度”的决心,这会让你像这样走捷径。现在你已经得到了一些快速但不可靠的东西。在非托管代码中获取托管异常非常难以诊断,所有上下文都消失了。
选项 1 和 3 是同一件事。两者都会生成互操作库,IDE 只是为您运行 Tlbimp 的等效项。
通常的指导在这里适用。首先做简单的事情,互操作库非常简单。只有当您能够真正衡量性能问题并且有一个现实的想法来解决它时,才考虑做真正困难的事情。我从未见过有人认为 C++/CLI 包装器是必要的。
Writing a wrapper in C++/CLI isn't that likely to be faster, the COM interop marshaller in the CLR is heavily optimized. It auto-generates machine code stubs from the interop library that you create when you add a reference to the COM server. A does a lot more work that's pretty invisible and very hard to do yourself, related to exceptions.
It makes sure that failure HRESULTs are properly converted to managed exceptions and that managed exceptions cannot leak into the COM server code. The "make it fast" resolve you'll have when you do this will make you cut corners like this. Now you've got something that's fast but unreliable. Getting a managed exception in unmanaged code is brutally hard to diagnose, all the context is gone.
Options 1 and 3 are the same thing. Both generate the interop library, the IDE simply runs the equivalent of Tlbimp for you.
The usual guidance applies here. Do the simple thing first, the interop library is incredibly simple. Only contemplate doing the really hard thing when you can actually measure perf problems and have a realistic idea what to do about it. I've never once seen anybody decide that a C++/CLI wrapper was necessary.
选项 2 的性能更高,但也不是很多,特别是考虑到 DLL 本身是用 VB6 编写的。
不确定选项 3 是否有效。
我个人会使用选项 1,但只需将互操作保存在安全的地方,这样我就可以继续重用相同的互操作,而不是每次添加引用时都创建它。
另一种选择是使用新的
动态
功能和后期绑定(使用Activator
来创建对象),但这绝对是性能较差的。Option 2 is more performant, but not much, especially considering the DLL itself is in VB6.
Not sure if option 3 works at all.
I would personally use option 1, but just keep the interop somewhere safe so that I just keep reusing the same interop and not creating it everytime I add the reference.
Another option is to use new
dynamic
features and late binding (usingActivator
to create the object) but that is definitely less performant of all.由于该组件使用 COM,因此最简单的方法是将其添加为引用并让 Visual Studio 构建代理。这对于 .net 代码来说将是非常直接和透明的。它的性能不会那么好,但很可能会满足您的需求。我会先这样做,因为它很简单,然后看看它的表现如何。
如果该组件不是 COM 组件,而只是一个标准的 c++ dll,那么其他两种方法可能是更好的选择。
Since the component is using COM, it will be easiest to add it as a reference and let visual studio build the proxies. This will be very strait forward and transparent to the .net code. It will not be quite as performant, but most likely it will suit your needs. I would do this first, since it is so easy, and then see how it performs.
If the component was not a COM component, and just a standard c++ dll, then the other two method would probably be a better choice.
由于数据的编组,对 COM 的调用很慢。我的意思是,与不跨越托管或 COM 边界的调用相比,速度较慢。
如果您需要在应用程序的性能关键部分对 COM 组件进行大量小型调用,您可以使用 C++ 包装(并组合)它们。
如果调用次数最少,或者它们不是性能关键的(但不是所有调用都对性能关键吗?),我只需添加对 COM dll 的引用。
总结 查找COM dll的引用,并测试性能。由于您从 VB6 迁移,您将获得巨大的性能提升(.Net 中的字符串处理速度要快得多)。
A call to COM is slow because of the marshalling of the data. With slow I mean, compared to a call where you do not cross a Managed or COM boundary.
If you need to do a lot of small calls to your COM component, in a performance critical piece of your application, you could wrap (and combine) them with C++.
If the number of calls is minimal, or when they are not performance critical (but aren't all calls performance critical?) I would simply add a reference to the COM dll.
Summary Go for the refence to the COM dll, and test the performance. Since you migrate from VB6, you will get an enourmous performance boost already (string handling in .Net is sooooo much faster).