gpt4 book ai didi

c++ - 如何在DLL内的成员函数中使用互斥锁/关键部分

转载 作者:行者123 更新时间:2023-12-02 10:37:56 24 4
gpt4 key购买 nike

我正在创建一个驻留在DLL中的COM类(带有ATL)。对于我的成员函数之一,根据某些条件,我想潜在地使用第三方库(Adobe的XMP SDK),必须对其进行初始化和终止。所以基本上,我将有一个成员函数,看起来像这样:

void CMyClass::MyMemberFunction()
{
SXMPMeta::Initialize();

// ...

SXMPMeta::Terminate();
}

现在,根据Adobe XMP库文档,

You must call the initialization and termination functions in a single-threaded manner . . . .



同时,我相信File Explorer可以在单独的线程上创建类的多个实例。因此,如果我正确理解了所有内容,听起来我将有一个关键部分,并且需要在库的初始化和终止周围使用互斥体(但是,如果那是错误的,请更正我)。

我不清楚该如何处理。我不确定是否应该使用 ATL critical section classes或CRITICAL_SECTION之一。 CRITICAL_SECTION似乎是一个不错的选择,但 example显示它正在main()中初始化。如果您在DLL中会怎样?我不想开始与DllMain()混淆。任何帮助或想法将不胜感激。

根据 gem 的建议,我尝试了以下方法:
struct XMPLibraryInitializer
{
XMPLibraryInitializer()
{
// Initialize libraries
if (!SXMPMeta::Initialize() || !SXMPFiles::Initialize())
{
XMP_StringPtr pszErrorMessage = "Libraries failed to load";
throw XMP_Error(kXMPErr_InternalFailure, pszErrorMessage);
}
ATLTRACE("\nXMP library initialized on thread %lu\n", GetCurrentThreadId());
}
~XMPLibraryInitializer()
{
// Terminate XMP libraries
SXMPFiles::Terminate();
SXMPMeta::Terminate();
ATLTRACE("\nXMP library terminated on thread %lu\n", GetCurrentThreadId());
}
};

HRESULT MyFunc()
{
// Statically initialize the Adobe XMP library
try
{
static XMPLibraryInitializer xmpLibraryInitializer;
}
catch (const XMP_Error & e)
{
return E_UNEXPECTED;
}

// ...

}

这似乎运行良好,除了我看到的输出是

XMP library initialized on thread 5820 ... XMP library terminated on thread 3104



对于不同的线程号有什么解释吗?如果数字不同,是否表示它不符合要求单线程初始化和终止的文档?

最佳答案

如果您要在程序退出之前一直保持简单的静态单例函数就足够了。
保证只能以一种有效的线程安全方式(从C++ 11开始)执行一次静态初始化,该方式通常涉及对保护标志的互斥体双重检查。

您将在无法确定已经设置ATX的每个地方调用它。在一些重复事务中调用它没有意义,但没有害处。因此,是否要在GiveMeAToken()中调用它,但不要在UseToken()中调用它,因为您知道必须先调用它才能获取 token ?

我更新了此示例,以显示如何保留简单的bool Initialize成功状态,尽管SXMPMeta::Initialize()的实际返回值可能更复杂:

struct SomeATXThing
{
bool good;
SomeATXThing()
{
good = SXMPMeta::Initialize();
}
~SomeATXThing()
{
if (good)
SXMPMeta::Terminate();
}
};

SomeATXThing* AtxEnsureSingleton()
{
static SomeATXThing someATXThing;
return someATXThing.good ? &someATXThing : nullptr;
}

请注意,单例的一个警告是它们以相反的顺序被破坏,直到其构造结束。其他一些独立的较早构造的单例在其销毁过程中一定不要依赖此单例的存在,但对于一个单例构造函数而言,在构造期间以及销毁期间再次调用另一个构造函数是安全的。除了ABEND之外,没有容易执行的规则。

您可以在对象(通常依赖于销毁后对象实例地址的 undefined 行为存在)处重新激活凤凰城,但是这很痛苦。

关于c++ - 如何在DLL内的成员函数中使用互斥锁/关键部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59379297/

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