- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
在单个 .exe 应用程序中,WinMain
入口点有一个 HINSTANCE
参数,它应该是一个伪句柄(因为等同于 GetModuleHandle(NULL)
返回一个伪句柄,根据 MSDN)。我想它是伪,因为有特殊值(例如NULL
表示入口点模块)和用于返回错误的常量(小于 32)。
MSDN 明确地将其描述为指向模块基地址的指针(现在相当于HMODULE
);我们知道这对于 16 位应用程序可能具有完全不同的含义,但在 32/64 位世界中每个进程都有自己的地址空间然后它的 exact 值是无用的,每个实例可能总是相同的并且绝对在其过程之外毫无意义。
综上所述,这是我的第一个问题:我们能否(正式地,尽管 MSDN 似乎自相矛盾)假设 HINSTANCE
是一个指针(即使老实说我不看不出有任何用处)还是最好假设它是一个(伪)句柄(它的值是不透明)?
假设它的值是不透明的,我的第二个问题:它的值是对每个进程还是每个线程有效?
我们可能认为进程句柄对每个进程都是有效的,但很少(极端)情况让我认为我们应该假设它对每个线程都有效。如果这些极端情况存在,那么(即使它通常看起来按预期每个进程工作)我们依赖于一个实现细节,一个未定义的行为可能会发生变化不同的架构、版本、环境。
让我们看一个我看到问题的案例(代码太简单了,我只描述场景):DLL 通常有一个共享代码部分,但它们也可能有(即使它很不常见)共享数据部分(例如跨进程共享大量数据或实现快速但不完善的 IPC 机制)。它可能不常见但可能(并且很容易实现,例如在 VC++ 中,只需很少的 #pragma
data_seg
和 comment(linker)
指令)。在这种情况下,我们知道(在我们的 DLL 中)我们无法比较 HINSTANCE
(因为它们可能具有相同的值)而且我们也不能信任的 IMO我们从线程 A(在我们的 DLL 中)获得的 HINSTANCE
与我们在线程 B 中获得的 HINSTANCE
是可比较的。简而言之:每次我们需要一个HINSTANCE
我们必须调用 GetModuleHandle(NULL)
以获取实际每个线程有效的。
作为 bonus 我也明白这如何适用于 HINSTANCE
当它来自 WinMain
时我们作为参数获取。理论上它是每线程的,但例如 CreateWindow()
将正确解析它(因为作用域是当前执行进程,当然假设调用线程有自己的消息循环)?
void createToolbox(const char* windowName, HINSTANCE hInstance) {
// ...
// Do we need this?
// HINSTANCE hInstance = GetModuleHandle(NULL);
CreateWindow(windowClass, windowName,
WS_OVERLAPPEDWINDOW,
0, 0, 640, 480,
0, 0, hInstance, NULL);
// ...
}
编辑 看来我完全错了,我确实记得 HMODULE 的线程关联,但它适用于 Windows Mobile...
If this parameter is NULL, GetModuleHandle returns a pseudo handle to the current process. [...] A pseudo handle is a special constant that is interpreted as the current thread handle. The calling thread can use this handle to specify itself when a thread handle is required.
显然,桌面应用程序并非如此(以及其他差异)。
最佳答案
进程中的每个模块都有一个模块句柄,它也是该模块的基地址。传递给 WinMain
的 hInstance
参数是进程主模块的基地址。因此,它在整个进程中都是有效的,因为进程有一个单一的虚拟地址空间。
传递给 WinMain
的 hInstance
参数总是等于 GetModuleHandle(NULL)
。
如果您愿意,您通常可以将模块句柄视为不透明的。也就是说,您通常不需要取消对指针的引用,只需将其传递给需要 HMODULE
参数的 API 函数即可。这些都不会改变该值在不同线程中是否有效。该值是每个进程的值。
我无法理解您的奖金问题。我怀疑这源于模块句柄是每个线程的错误假设。一旦您接受模块句柄在进程内的所有线程中具有相同的含义,您的绝大多数问题就会消失。
关于c - HINSTANCE 跨线程有效吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29817673/
注册窗口类时需要填写WNDCLASS结构,它有一个 hInstance领域: typedef struct { UINT style; WNDPROC lpfnWndProc;
为什么 WinMain 可以有两种返回类型? 如果我删除它,将报告此警告: warning C4007: 'WinMain' : must be '__stdcall' 或者我错误地读取了 int W
win32应用程序的HINSTANCE被传递给WinMain,但是有没有其他方法可以确定当前的HINSTANCE(如果你不知道,我对win32编程很陌生!)?我需要在库内创建一个窗口(因为该库是跨平台
我用 CreateWindow创建主窗口。 hInstance在 WNDCLASSEX指定注册类的实例。所以我需要hInstance在 CreateWindow找到它的功能。 我用 CreateWin
在单个 .exe 应用程序中,WinMain 入口点有一个 HINSTANCE 参数,它应该是一个伪句柄(因为等同于 GetModuleHandle(NULL) 返回一个伪句柄,根据 MSDN)。我想
我正在使用 ShellExecute 从 C++ 生成一个应用程序,所以我有应用程序的 HINSTANCE。 现在如何使用 HINSTANCE 关闭它?我可以使用 WaitForSingleObjec
我正在编写一个缓存处理程序,它需要应用程序的每个实例都有一个唯一的 ID 号,这样当有人在两个实例中打开两个项目时,缓存就不会混淆。根据this thread ,似乎传递给 WinMain 的 HIN
我使用 ShellExecute 从我当前的应用程序创建一个新的应用程序实例。我想获取该应用程序的 HWND。是否可以从 HINSTANCE 获取 HWND 或者我需要使用 EnumWindows?
我在 VC++ 中创建了一个 DLL 作为 Win32 项目 DLLMAIN函数是 BOOL APIENTRY DllMain( HMODULE hModule,
我正在尝试使用 BTMemoryModule.pas 单元从资源加载 dll,但收到此错误无法加载指定的模块。这些是我使用 BTMemoryModule 从 exe 调用的 dll 中的过程: pro
标题已经说了。 请参阅真实世界示例:https://learn.microsoft.com/en-us/windows/desktop/api/shellapi/nf-shellapi-findexe
我不得不更新一些字符串,因为多年来发生了一些变化,但现在它无法编译。这最初是在 VS2010 中完成的。它是在 C 的 Win32 API 中编码的。现在我使用的是 2012,它抛出了这些错误: 1
考虑以下代码: #include LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI wWinMain(HINSTANC
我正在使用 Shell 命令启动一个进程。我的开发环境是 C++/QT Creator/QT Libraries 和 Windows APIs。 如何处理 HINSTANCE 返回值? if (hIn
示例代码如下: CString CMeetingScheduleAssistantApp::GetStudyPointDescriptionEx(bool b2019Format, const int
有没有一种方法可以从 WinAPI 中转发声明 HINSTANCE 类型,而不包括完整的(和大的)windows.h header ? 例如,如果我有一个拥有 HINSTANCE mInstance
在使用 Windows API 进行编程时,我总是将 WinMain 中的 HINSTANCE 立即设为全局变量。如果我想做一个 OK 按钮,我会这样做(给定全局 HINSTANCE g_hInsta
我正在使用 -Wbad-function-cast 标志在 gcc 上编译程序。 gcc 显示以下警告: 转换与函数类型不匹配 这是警告行:int ret = (int) FindExecutable
Win32 应用程序。在 MyRegisterClass 中,wc.hInsance = hInstance。显然“hInstane 是一个未定义的标识符。这是为什么?我使用的是 Visual Stu
如何在不使用全局变量的情况下获取 winMain 的 HWND hwnd 的 hInstance 应用程序句柄?我正在尝试创建一个发送到 LRESULT CALLBACK 的对话框,以使其显示某些菜单
我是一名优秀的程序员,十分优秀!