为啥接口上的“添加 IDL 方法”将方法添加到模块以及 CoClass?

Posted

技术标签:

【中文标题】为啥接口上的“添加 IDL 方法”将方法添加到模块以及 CoClass?【英文标题】:Why does "Add IDL Method" on an Interface add the method to the Module as well as to the CoClass?为什么接口上的“添加 IDL 方法”将方法添加到模块以及 CoClass? 【发布时间】:2021-06-26 02:17:12 【问题描述】:

这个问题是关于使用 Visual Studio 2019 使用 ATL 构建进程外 COM 服务器的。 (我以前在 Borland 做过,但这是我第一次使用 MSVC)。

我使用 ATL 项目向导创建了一个名为 MyObjectsProject 的项目。这在文件 MyObjectsProject.cpp 中创建了模块 class CMyObjectsProjectModule : public ATL::CAtlExeModuleT<CMyObjectsProjectModule>

然后我通过“添加> ATL 简单对象”添加了一个简单对象MyObject,如the documentation 中所述。这创建了文件MyObject.cppMyObject.h,其中包含一个接口IMyObject 和CoClass CMyObject。到目前为止一切顺利。

我在类视图中转到IMyObject,然后右键单击“添加> 方法”并为其提供一些详细信息,然后它将方法声明添加到MyObject.h 中的CMyObject,并将一个空定义添加到@987654333 @ 为 CMyObject::method_name() 。到目前为止,一切都很好(再次)。

但同时,它在MyObjectsProject.cpp 中添加了方法声明和定义,作为CMyObjectsProjectModule 的类成员。此外:

永远不会调用CMyObjectsProjectModule::method_name() 版本——当我通过客户端使用COM 服务器,并在MyObject 的实例上调用IMyObject::method_name() 时,它会按预期执行定义为CMyObject::method_name() 的版本。李> 我可以删除CMyObjectsProjectModule中的方法声明和定义,没有错误。

如果添加一个属性,也会发生同样的事情。此外,“完成操作...”运行大约需要 45-50 秒。


我的问题是: 将方法添加到 Module 和 CoClass 背后的原因是什么,何时调用该版本的 Method? (或者这只是一个错误,根本不应该添加到模块中?)

在 Borland IDE 中,类似的函数不会向模块添加方法。


编辑:最初发布了名为 MyProject 的项目的问题,但问题仅在项目名为 MyObjectsProject 时出现。我最初在问题中使用了与我观察到的问题不同的名称,但现在已经编辑了问题并使用问题中的确切名称进行了复制。

【问题讨论】:

我没有在我的 2019 16.9.2 上重现(以前从未见过),当然这不应该发生,任何东西都不应该添加到模块中。我只在 MyObject.idl、MyObject.cpp、MyObject.h 上得到一个 method_name 该项目最初是在 VS 2019 中创建的,是哪个构建的? ATL 向导在 VS 2017 中的某个时候被破坏,并经历了几轮修复,这些修复溢出到早期的 VS 2019 版本中。 @dxiv 是的,新项目(我开始了一个新项目来重现)。 VS 专业版 2019 版本 16.9.2 另一个有点奇怪的事情;在类视图中,IMyOjbect 出现了 3 次。两次使用界面图标,一次使用线条和两个点图标。对每个使用“转到定义”:一个转到.idl 文件,两个转到MyObject_i.h 文件。我一直在对前者进行“添加>添加方法”。填写完对话框后,弹出“Completing operation...”,申请大概需要50秒左右,其他机器也不慢 @dxiv 现在已编辑问题——如果您尝试在课堂视图中重现现有的问题。右键单击 CMyProjectModule 并将其“重命名”为 CMyObjectsProjectModule 然后应该会出现问题 【参考方案1】:

方法不应该被添加到Module中,并且不应该花费45-50秒来添加方法。

每当 CoClass 名称是模块名称的初始子字符串时,似乎就会出现问题。

例如,CMyObject 的模块为 CMyObjectsProjectModule,但不会出现在 CMyObject 的模块为 CMyProjectModule 的情况下。

当问题发生时,CMyObject > Derived Types > 的类视图会显示派生类型 CMyObjectCMyObjectsProjectModule

我猜这是在“推导”两种类型之间的派生类型关系,其中一种是另一种的初始子字符串;此外,“添加方法”的行为决定将该方法添加到它认为是已添加该方法的 CoClass 的派生类型的所有内容中。


结论:这似乎是 IDE 中的一个错误(或至少是有问题的设计);为了解决这个问题,您可以将模块重命名为以一些唯一的子字符串开头,这样所有 CoClass 都不会与模块的初始子字符串重合。

类设计器工具没有将这两种类型显示为派生的(即,该工具似乎没有使用与类视图窗口相同的启发式方法来确定一种类型是否派生自另一种类型)

【讨论】:

(+1) 你可能想在feedback 上提交一份正式的错误报告并将其命名为The big ATL wizard misery 第 2 季 ;-) FWIW 子字符串错误甚至不会在第一场比赛中停止。如果你添加另一个简单的对象MyObj 并添加一个方法alt_method() 到它,VC++ 将冻结几分钟,然后一旦它恢复生机,新方法就会出现在所有CMyObjCMyObject (虽然不在 IMyObject 的 IDL 中)和 CMyObjectsProjectModule

以上是关于为啥接口上的“添加 IDL 方法”将方法添加到模块以及 CoClass?的主要内容,如果未能解决你的问题,请参考以下文章

为啥将返回类型添加到 void 返回方法会导致 MissingMethodException

为啥 Laravel 会成为最成功最流行的 PHP 框架

为啥 Java 8 没有在 `java.util.concurrent.locks.Lock` 接口中添加 `withLock` 默认方法?

redis监控

为啥在我的 HttpPost 方法 Ajax 调用中,控制器上的参数为空?

为啥 Java 8 接口方法中不允许使用“final”?