【发布时间】:2020-11-10 16:04:27
【问题描述】:
最近我开始从 Microsoft 文档中学习 WIN API,并决定使用我的 IDE 功能查看每个细节。 LoadIconA 是一个以 HINSTANCE 和 LPCSTR 作为参数的函数。我们将 IDI_APPLICATION 作为第二个参数传递。这是一个扩展为的宏
#define IDI_APPLICATION MAKEINTRESOURCE(32512) // winuser.h
此外,MAKEINTRESOURCE 扩展为 ANSI 或 UNICODE 等效项。我正在查看 ANSI 等效项。
#define MAKEINTRESOURCEA(i) ((LPSTR)((ULONG_PTR)((WORD)(i)))) // winuser.h
在这里,我注意到整数 I(此处为 32512)最终被类型转换为 LPSTR,该 LPSTR 被传递给 LoadIconA 函数。但是当我做同样的事情时
#include <windows.h>
#include <iostream>
int main(){
LPCSTR hello = MAKEINTRESOURCEA(32512);
std::cout << hello << std::endl;
}
我的程序崩溃了。 有人知道这里发生了什么吗?
另外,我没有注意到任何库依赖项。抱歉,问题标题,我没有找到任何合适的标题。
【问题讨论】:
-
"...将整数值转换为与资源管理功能兼容的资源类型。..." docs.microsoft.com/en-us/windows/win32/api/winuser/… "...返回值应仅传递给明确表明它们接受 MAKEINTRESOURCE 作为参数的函数。.."
-
我并没有声称当你做同样的事情时它会起作用,但我不明白为什么你期望在你做不同的事情时得到相同的结果
-
@vectorX
LoadIconA"...要加载的图标资源的名称。或者,此参数可以在低位包含资源标识符,在高位包含零-order word。使用 MAKEINTRESOURCE 宏来创建这个值...." docs.microsoft.com/en-us/windows/win32/api/winuser/… -
听起来像在
LoadIconA内部,它确定 LPCSTR 参数是否在 MAKEINTRESOURCE 创建的范围内,如果是,它从不尝试直接将值用作字符串,而是将其用作其他字符串容器的索引。但是,当您cout << hello时,您并没有这样做-您假设它是指向文本的指针,并且遵循无效的指针。因此,崩溃。 -
非常非常非常古老的 Windows“技巧”。它是要么资源ID或指向字符串的指针。在 Windows 中,地址空间的前 64K 总是无效的。因此,如果指针值 devblogs.microsoft.com/oldnewthing/20110217-00/?p=11463