28

I'm importing WinApi functions, writing callbacks etc. (example) in C# and always wonder:

  • what do they mean ? LRESULT as last result ? W-PARAM ? L-PARAM ?
  • how to safely "wrap" them
    • WPARAM and LPARAM contain structs sometimes. So I need to use them as IntPtr. How about LRESULT ? Am I safe with int or better IntPtr ?

What type do I use for LRESULT in C# ? int or IntPtr ?

4

4 回答 4

88

在此处输入图像描述

那是查尔斯·西蒙尼(Charles Simonyi),微软应用软件组的前负责人,该组开发了 Word 和 Excel。他是制定标识符命名标准的人。由于没有人知道如何发音他的姓氏,他们选择了他出生的国家并称之为匈牙利符号。Windows 小组也采用了它,但选择了“坏”的 System Hungarian。选择标识符的第一个字母以说明变量的类型。与“好”类型相反,Apps Hungarian 使用逻辑类型名称而不是物理类型名称选择前缀。西蒙尼的版本。

所以它在 Long 中是 L,在 Word 中是 W。LPCWSTR 就是这样一个笨蛋,指向常量宽字符串的长指针。System Hungarian 的一个明显问题是,当架构发生变化时,它不再那么好用了。最初选择用于 16 位操作系统(L=32 位,W=16 位),迁移到 32 位而不更改名称(W=32 位),我们现在是 64 位(L= W=64 位)。

所以忽略这些前缀,它们只是一个历史事故。您确实必须为 LRESULT 类型选择 IntPtr,它当然可以是 64 位版本的 Windows 上的 64 位值。当您不这样做时,很难诊断出问题,这是一个常见问题。

题外话,你在照片背景中看到的模糊图像也是关于西蒙尼的一个有趣的花絮。微软与员工分享了它的巨大成功,并将他们中的许多人变成了千万富翁。您在背景中看到的是停靠在国际空间站的航天飞机的照片。西蒙尼是七位“太空游客”之一,他给自己买了一张国际空间站的票。唯一两次这样做的人,让他损失了 6000 万美元 :)

于 2013-07-25T08:04:39.413 回答
7

这些名字来自历史原因。在 WIndows16 位 WPARAM 的时代,在匈牙利符号中表示 Word-Parameter 和 LPARAM Long-Parameter。移动到 32 位将两者折叠为相同的大小(32 位整数),但名称保持不变。LRESULT 意味着长结果,并且由于历史原因再次保留名称。当 windows64 位出现时,另一个变化发生了。请在 MSDN 中查看此处以获取完整列表。详细说明:LPARAMLRESULT都是 LONG_PTR 的 typedef 其中 LONG_PTR 是:

#if defined(_WIN64)
 typedef __int64 LONG_PTR; 
#else
 typedef long LONG_PTR;
#endif

WPARAMUINT_PTR的 typedef ,其中UINT_PTR是:

#if defined(_WIN64)
 typedef unsigned __int64 UINT_PTR;
#else
 typedef unsigned int UINT_PTR;
#endif

您基本上可以看到最终指向相同大小位的类型:唯一真正的区别是您使用的是 Windows 32 还是 64。就使用意义而言,它们是您可以根据窗口过程需要使用的通用参数做。通常,由于几个数字是不够的,因此使用复杂数据结构的指针并将它们的值作为 WPARAM 或 LPARAM 传递,因此除非您关注上下文,否则您无法分配任何特定含义。

于 2013-07-25T07:20:09.880 回答
3

这是匈牙利符号的一个例子:

  • LLPARAM和中都LRESULT表示“长”,表示 32 位int
  • winWPARAM表示“单词”(过去是 16 位int,但现在也是 32 位int——至少在针对 32 位架构时)

类型名称/别名的其余部分应该暗示它们的含义,即LRESULT包含某种结果值,LPARAMWPARAM用于参数变量。

wParam和参数内容的实际含义lParam取决于发送的特定消息;它们只是消息参数的通用存储桶。因此,您很可能无法规避不安全的类型转换。

于 2013-07-25T07:16:24.997 回答
2

LPARAM 是 LONG_PTR 的 typedef,在 win32 上是 long(有符号 32 位),在 x86_64 上是 __int64(有符号 64 位)。

WPARAM 是 UINT_PTR 的 typedef,在 win32 上是 unsigned int(无符号 32 位),在 x86_64 上是 unsigned __int64(无符号 64 位)。

typedef UINT_PTR WPARAM;

typedef LONG_PTR LPARAM;

在 c# 中,您可以使用IntPtr

请参阅LPARAM 和 WPARAM 的定义是什么?

于 2013-07-25T07:22:54.217 回答