Overloads in COM interop (CCW) - IDispatch names include suffix (_2, _3, etc)(COM 互操作 (CCW) 中的重载 - IDispatch 名称包括后缀(_2、_3 等))
问题描述
我有一个包含几个类的托管程序集,这些类具有重载方法.我通过
I have a managed assembly containing a few classes, and those classes have overloaded methods. I expose the assembly to COM/IDispatch callers via
[ComVisible(true)]
..并且还在程序集本身上设置正确的 Guid.我没有为 COM 互操作定义显式接口.这一切都是动态完成的.我在托管 DLL 上运行 regasm.exe/codebase
并将其注册为 COM 互操作.
..and also setting the proper Guid, on the assembly itself. I do not define an explicit interface for the COM interop. It's all done dynamically. I run regasm.exe /codebase
on the managed DLL and it registers it for COM interop.
当我运行 OleView 时,我可以看到程序集中各个类的 ProgId.但是,浏览这些 ProgId 并展开 IDispatch 节点,这些类没有 TypeLib 信息.
When I run OleView, I can see the ProgId's of the various classes in the assembly. But, browsing into those ProgIds, and expanding IDispatch node, there is no TypeLib information for these classes.
即便如此,我可以从脚本调用接受零参数的方法或接受一个参数的方法.如果还有一个接受多个参数的重载,我不能按名称调用该方法.我一直得到的错误是
Even so, from a script, I can invoke a method that accepts zero arguments or a method that accepts one argument. If there is also an overload that accepts more than one argument, I cannot invoke that method by name. The error I get, consistently, is
Microsoft VBScript runtime error: Wrong number of arguments or invalid property assignment: <methodname>
据此,我了解到 COM/IDispatch 客户端无法正确解析通过 COM 互操作公开的对象上的重载方法.
From this I understood that COM/IDispatch clients were not able to properly resolve overloaded methods on an object exposed via COM interop.
然后我添加了
[ClassInterface(ClassInterfaceType.AutoDual)]
...对每个有问题的课程.在 DLL 上的 regasm.exe
之后,我可以在 IDispatch 节点下看到每个方法的 typelib 信息.
...to each of the classes in question. After regasm.exe
on the DLL, I can see typelib information for each method, under the IDispatch node.
我发现重载的方法会自动获得一个包含附加后缀的名称.MethodX 将在自动生成的 typelib 程序集中公开重载为 MethodX、MethodX_2、MethodX_3 等.
What I found is that overloaded methods automatically get a name that includes an appended suffix. MethodX will expose overloads in the auto-generated typelib assembly as MethodX, MethodX_2, MethodX_3, and so on.
我发现通过引用带有这些后缀的方法名称,我可以调用重载方法,尽管不是使用通用名称.
And I found that by referencing the method names with those suffixes, I could invoke overloaded methods, although not with the common name.
更有趣的是,如果我随后从类中删除 [ClassInterface(ClassInterfaceType.AutoDual)]
,我可以仍然以这种方式调用重载方法,从而避免参数数量错误或属性分配无效
错误.
More interestingly, if I then removed the [ClassInterface(ClassInterfaceType.AutoDual)]
from the classes, I could still invoke the overloaded methods in this way, thus avoiding the Wrong number of arguments or invalid property assignment
error.
我的问题是:这种行为 - 将数字后缀附加到成员名称 - 稳定吗?记录在案?可信?
My question is: is this behavior - appending numeric suffixes to the member names - stable? documented? dependable?
推荐答案
COM 不支持方法重载,所以.NET COM Interop 层不得不即兴发挥.我不确定您所描述的名称修改是否在任何地方都有记录,但即使是这样,我也不认为使用它是一个好主意 - 对于 COM 用户来说,它仍然是相当不方便的 API.如果你想向 COM 公开你的类,最好的方法是编写一个独特的 COM 友好的 [ComVisible]
接口,并隐藏类本身.以 COM 友好的方式处理重载的正确方法是使用带有一些 [Optional]
参数的单一方法(并委托给相应的 .NET 重载).
COM does not support method overloading, so .NET COM Interop layer has to improvise. I'm not sure if name mangling as you described as documented anywhere, but even if it is, I don't think that using it is a good idea - it's still pretty inconvenient API for COM users. If you want to expose your classes to COM, the best way is to write a distinct COM-friendly [ComVisible]
interface, and hide the class itself. The correct way to handle overloads in a COM-friendly way would be have a single method with some [Optional]
arguments (and delegate to your corresponding .NET overloads).
这篇关于COM 互操作 (CCW) 中的重载 - IDispatch 名称包括后缀(_2、_3 等)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:COM 互操作 (CCW) 中的重载 - IDispatch 名称包括后缀(_2、_3 等)
- 带问号的 nvarchar 列结果 2022-01-01
- 是否可以在 .Net 3.5 中进行通用控件? 2022-01-01
- 在 C# 中异步处理项目队列 2022-01-01
- 在 LINQ to SQL 中使用 contains() 2022-01-01
- 使用 rss + c# 2022-01-01
- Windows 喜欢在 LINUX 中使用 MONO 进行服务开发? 2022-01-01
- C# 通过连接字符串检索正确的 DbConnection 对象 2022-01-01
- CanBeNull和ReSharper-将其用于异步任务? 2022-01-01
- Azure Active Directory 与 MVC,客户端和资源标识同一 2022-01-01
- 为什么 C# 中的堆栈大小正好是 1 MB? 2022-01-01