为什么MAKEINTRESOURCE()有效?

时间:2010-08-31 15:29:49

标签: c++ c windows winapi

宏定义为:

#define MAKEINTRESOURCEA(i) ((LPSTR)((ULONG_PTR)((WORD)(i))))
#define MAKEINTRESOURCEW(i) ((LPWSTR)((ULONG_PTR)((WORD)(i))))

为什么这可用于指示资源ID(16位无符号整数)或其名称(指向char数组的指针)? 这是否有效地将地址空间(在32位系统上)限制为16位?否则,系统如何知道我使用的是ID还是姓名?

3 个答案:

答案 0 :(得分:21)

这是有效的,因为Windows不允许映射页面为地址空间的前64 KB。捕获空指针引用。但我认为还要捕获从16位版本的Windows转换而来的程序中的指针错误。

副作用是,它允许可靠地区分打包到指针值的资源ID,因为它们总是指向不可映射的内存。

答案 1 :(得分:17)

MAKEINTRESOURCE宏只是在数字参数和字符串指针之间进行转换。生成的字符串指针无效,无法作为资源名称取消引用。但是,资源处理API按其绝对值检测此类指针,并将它们视为资源ID而不是资源名称。由于C风格的API不支持重载,因此它们无法定义两个函数,如:

HICON LoadIcon(HINSTANCE hInstance,LPCTSTR lpIconName);
HICON LoadIcon(HINSTANCE hInstance,UINT resourceId);

因此,API开发人员决定在两种情况下使用相同的功能,为API用户提供MAKEINTRESOURCE宏。我相信两种不同的功能可能看起来更好:

HICON LoadIconByName(HINSTANCE hInstance,LPCTSTR lpIconName);
HICON LoadIconById(HINSTANCE hInstance,UINT resourceId);

但这不是Windows API的实现方式。有效资源ID始终小于可能的最小指针值。资源名称参数在没有此宏的情况下传递给API,其值不受限制。

答案 2 :(得分:4)

是的,它确实限制了地址空间,但没有您想象的那么多。他们有效地划分了64GB的4GB地址空间。 64KB的大部分(如果不是全部)已经被保留用于Windows上的其他内容,因此有效的损失是无效的。

总的来说,它节省了空间,因为它们不需要额外的信息来区分指针和整数ID。这是在过去的糟糕时期发明的,当时空间非常宝贵。