Visual c++ 办公室自动化与#进口有害?

Visual c++ 办公室自动化与#进口有害?,visual-c++,com,import,office-automation,Visual C++,Com,Import,Office Automation,国家: […]它非常强大,但通常不推荐,因为 与一起使用时通常会出现的引用计数问题 Microsoft Office应用程序。[……] 这里具体指的是哪些引用计数问题? 例如,它是否适用于特定示例 与示例中类似,我只想打开Outlook,创建约会,完成 我想使用#import,但这句话让我感到害怕…当两个或多个对象直接或间接地相互引用时,就会发生这种情况。在COM中,这意味着循环链接的对象彼此调用了IUnknown::AddRef 在使用Excel自动化的情况下,如果将事件处理程序(接收器)连接

国家:

[…]它非常强大,但通常不推荐,因为 与一起使用时通常会出现的引用计数问题 Microsoft Office应用程序。[……]

这里具体指的是哪些引用计数问题? 例如,它是否适用于特定示例

与示例中类似,我只想打开Outlook,创建约会,完成

我想使用#import,但这句话让我感到害怕…

当两个或多个对象直接或间接地相互引用时,就会发生这种情况。在COM中,这意味着循环链接的对象彼此调用了
IUnknown::AddRef

在使用Excel自动化的情况下,如果将事件处理程序(接收器)连接到Excel对象源事件(通过
IConnectionPoint::advice
),则可能发生这种情况。这样,您可能保留了对例如
应用程序
对象的引用,而
应用程序
对象保留了对接收器的引用

这个问题并不特定于VC++
#import
指令生成的智能指针。这是关于当您不再需要COM对象时如何处理它们的关闭。您应该显式断开所有已建立的连接(即执行
IConnectionPoint::Unadvise
),并调用对象可能公开的任何显式关闭API(例如
Workbook::Close
Application::Quit
)。然后您应该显式地释放引用(例如,在智能指针上调用
workbookPtr.release()


这就是说,如果您不处理任何来自Excel的COM事件,您就不必太担心,创建循环引用的可能性很低。此外,Excel是一个进程外COM服务器,COM具有一些适当的功能来管理进程外服务器的生命周期。但是,当应用程序仍处于打开状态时,Excel进程将保持活动状态,直到对其对象的所有引用被释放,或者调用了
application::Quit

这是非常荒谬的。借助#import编程Office互操作是样板和推荐的方式。它自动生成的智能指针类型明确旨在为您自动完成引用计数,这样您就不会忘记调用Release()。有一些尖锐的边缘,你必须理解智能指针可以做什么和不能做什么

这对于所有在一个代码框架后面的团队来说是另一个标准。这些样本是由上海的一个支持团队创建的,该团队最初受雇于帮助MSDN论坛。这些人没有你所期望的微软程序员在Redmond工作的那种证书,他们的代码片段也没有被审查。其中一些完全是考虑不周的。如果你曾在MSDN论坛上提问,并看到他们发布的答案,那么你知道我的意思

他们的Solution2.cpp样本通过IDispatch使用后期绑定。这无疑是与Office进行互操作的困难之路,在编写代码时没有任何帮助。编写方法调用时,IntelliSense无法为您提供任何有用的信息,编译器也无法告诉您缺少参数或参数类型错误。您的程序将在运行时失败,并出现不透明的错误代码,如DISP_E_BADVARTYPE或DISP_E_BADPARAMCOUNT。并且必须显式地进行Release()调用,这当然会使错过一个调用变得更容易。使用智能指针时没有的问题,它们会自动完成和类型检查。您可以亲眼看到Solution1.cpp的大小和可读性

诊断错过的Release()调用很容易,您的程序将完成,但您仍会看到Outlook.exe在任务管理器中运行。不管怎样,当你调试你的程序,发现一个bug并停止程序进行修正时,也会发生一些你已经习惯于检查的事情。当然,这也会阻止调用Release(),以便Outlook继续运行。你必须自己杀了它


请考虑用C语言或VB.NET等托管语言编写这类代码。如果您有问题,您将得到更多的帮助,并且您将找到许多示例代码。垃圾收集器永远不会忘记发出释放调用。这样做有点慢。

太好了,谢谢!我知道循环引用,但我不知道这是这一声明的原因。因此,我可以安全地使用#import并牢记这一点。@divB,除非您处理事件,否则执行“正常级别的预防措施”。否则,请执行“高级预防措施”,并在处理特定Excel对象时显式释放任何智能指针。如果您的应用程序终止,但Excel.exe仍在进程列表中挂起超过几秒钟,这将是一个坏迹象。