为什么在WinMain和wWinMain中存在prevInstance,如果它总是NULL

Why does prevInstance exist in WinMain and wWinMain if it is always NULL

本文关键字:如果 NULL prevInstance 存在 WinMain wWinMain 为什么      更新时间:2023-10-16

由于我是初学者,这可能是一个非常基本的问题。我正在启动DirectX 11,在创建我的第一个应用程序时,使用了wWinMain,在搜索WinMain和wWinMain之间的差异时,我遇到了这个参数prevInstance。

根据MSDN,

prevInstance总是空的,因为它总是空的,为什么它存在(因为它是合乎逻辑的,认为创作者不会给一个无用的参数)。(引自书中)

,如果您需要一种方法来确定先前的实例是否存在应用程序已经运行,文档建议创建使用CreateMutex创建一个唯一命名的互斥锁。尽管互斥会创建时,CreateMutex函数将返回ERROR_ALREADY_EXISTS。

什么是互斥锁,如何使用它(一个好的链接就足够了)。看起来需要一个方法来查找应用程序的另一个实例是否存在,prevInstance应该有一个指向它的指针或引用,这显然不是这种情况,因为它是空的。为什么会这样,prevInstance的作用是什么?

Raymond Chen的博客几乎完全致力于讨论Windows API中那些对我们来说很"奇怪"的方面。幸运的是,他有一篇博客文章回答了这个问题:

在16位的Windows中,有一个函数叫做GetInstanceData。这函数接受一个HINSTANCE、一个指针和一个长度,并复制内存从那个实例到当前实例。(这有点相当于ReadProcessMemory的16位,但限制是第二个和第三个参数必须相同。)

这就是hPrevInstance参数为WinMain的原因。如果hPrevInstance是非null的,那么它就是副本的实例句柄已经在运行的程序。你可以使用GetInstanceData来从上面复制数据,让你更快地离开地面。例如,您可能希望将主窗口句柄从前一个窗口中复制出来实例,以便您可以与它通信。

是否hPrevInstance是NULL或不告诉你你是否是程序的第一份拷贝。在16位Windows下,只有第一个一个程序的实例注册了它的类;第二次及后续实例继续使用由第一个实例。(事实上,如果他们尝试,注册将会失败因为这个类已经存在了。)因此,所有16位的Windows程序跳过类注册,如果hPrevInstance是非空。

设计Win32的人发现他们遇到了一些问题是时候移植WinMain了:为hPrevInstance传递什么?的毕竟,整个模块/实例的东西在Win32中是不存在的单独的地址空间意味着跳过的程序在第二个实例中重新初始化将不再工作。所以Win32总是传递NULL,使所有程序都认为它们是第一个。

当然,除了兼容性原因,hPrevInstance现在与Windows API无关,MSDN建议您使用互斥锁来检测应用程序的先前实例。

互斥代表互斥。您可以参考CreateMutex()的MSDN文档。有很多使用互斥体来检测应用程序以前的实例的例子,比如这个。基本思想是创建一个具有您想出来的唯一名称的互斥锁,然后尝试创建那个命名的互斥锁。如果CreateMutex()ERROR_ALREADY_EXISTS失败,您就知道您的应用程序的一个实例已经启动了。

prev实例参数用于16位Windows兼容性。我想这在WinMain的MSDN参考中有说明,至少过去是这样的