gpt4 book ai didi

c++ - Helper 类具有隐藏的 COM 依赖项;谁调用 CoInitialize?

转载 作者:行者123 更新时间:2023-11-28 01:42:10 24 4
gpt4 key购买 nike

我有一个帮助程序类,它为主机应用程序提供一些诊断 API。隐藏实现依赖于 WMI,它通过 Windows COM 接口(interface)访问。

实现一个“COM 感知”的类需要一些开销,以调用 CoInitialize/Ex 的形式。 ,使用适当的单元模型(单线程/多线程)。我不确定负责设置它 - 我的助手类,还是消费者。

那么,我的问题是:谁负责调用 CoInitializeCoUninitialize : 我的助手类,还是主机应用程序?除了帮助程序类之外,宿主应用程序中对 COM 的附加依赖性可能为零。

选项 A:助手类调用 CoInitializeCoUninitialize在构造函数和析构函数中

此选项很方便,并且有效地“隐藏”了 COM 依赖项。但是,父应用程序可能已经初始化 COM,也可能还没有,它可能匹配也可能不匹配助手类假定的单元模型。如果模型没有对齐,辅助类将收到来自 CoInitialize 的错误。 .

选项 B:助手类产生一个单独的线程,并调用 CoInitialize在后台线程上有一个单线程单元。所有接口(interface)调用都分派(dispatch)到后台线程并返回。

这有助于确保助手类有一个“干净的状态”来使用,并避免在任何单个线程上重复进行 COM 初始化。它还增加了我的助手类实现的复杂性,并以线程切换和握手的形式增加了开销。

选项 C:在文档中做一个注释,并要求主机应用程序处理对 CoInitialize 的所有调用和 CoUninitialize , 在使用辅助类之前

这使得该类使用起来稍微不那么“方便”,因为用户在使用该类之前有额外的初始化步骤。它还要求类的使用者实际阅读文档,这看起来很危险。

最佳答案

具有一些智慧的选项 A 似乎是一个不错的选择。这假定您不关心正在使用的线程模型。如果这样做,则需要明确声明助手的客户端不应初始化 COM,以便它可以指定线程模型。

class HelperThatRequiresCOM
{
public:
HelperThatRequiresCOM() : m_CoUninit(false)
{
// Attempt to init COM as a STA
HRESULT ciResult = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
if(ciResult == S_OK || ciResult == S_FALSE)
m_CoUninit = true; // COM initialized or already initialized.
else if(ciResult == RPC_E_CHANGED_MODE)
m_CoUninit = false; // COM initialized as MTA
}

~HelperThatRequiredCOM()
{
if(m_CoUninit == true)
CoUninitialize();
}

private:
bool m_CoUninit;

};

这将尝试初始化 COM。如果它已经初始化为 STA,或者刚初始化为 STA,它会记住该信息,以便稍后调用 CoUninitalize

如果 COM 已经初始化为 MTA,它会记住这一点,并且不会在以后CoUninitialize

这允许调用线程自行初始化 COM,如果没有,您可以自己初始化它。

关于c++ - Helper 类具有隐藏的 COM 依赖项;谁调用 CoInitialize?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46689491/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com