【问题标题】:Difference between LPVOID and void*LPVOID 和 void 之间的区别*
【发布时间】:2010-01-01 05:32:22
【问题描述】:

我可以在 C 中使用 void* 代替 LPVOID 吗?

或者LPVOID 执行一些比void* 更特殊的功能。

【问题讨论】:

    标签: c


    【解决方案1】:

    C 中没有 LPVOID 类型,这是 Windows 的东西。

    存在这类事情的原因是,底层类型可以在不同版本之间更改,而不会影响您的源代码。

    例如,假设 Microsoft 的 C 编译器的早期版本有一个 16 位 int 和一个 32 位 long。他们可以简单地使用:

    typedef long INT32
    

    而且,瞧,你有你的 32 位整数类型。

    现在让我们再过几年,Microsoft C 使用 32 位 int 和 64 位 long。为了使您的源代码仍然正常运行,他们只需将typedef 行更改为:

    typedef int INT32
    

    这与您在 32 位整数类型中使用 long 时必须做的相反。您必须检查所有源代码并确保更改了自己的定义。

    从兼容性的角度(不同版本的 Windows 之间的兼容性)来看,使用 Microsoft 的数据类型要干净得多。

    在回答您的具体问题时,使用void* 代替LPVOID 可能没问题提供了 LPVOID 的定义预计不会改变。

    但我不会,以防万一。你永远不知道微软是否会在未来引入一些不同的方法来处理通用指针,这会改变LPVOID 的定义。使用 Microsoft 的类型并不会真正失去任何东西,但如果他们更改定义并且您决定使用底层类型,您可能需要在未来做一些工作。

    您可能不会认为指针会不受这种变化的影响,但是在最初创建 Windows 的 8088 天里,指针和内存模型(小、小、大、巨大等)有各种各样的怪异之处即使在相同的环境中,指针也可以具有不同的大小。

    【讨论】:

    • 感谢 Pax,您的回答很好。
    【解决方案2】:

    LPVOID 只是 void* 的 Windows API typedef

    【讨论】:

    • 有人知道为什么这个 typedef 有用的历史吗?我怀疑它与 16 位和 32 位有一些关系。
    • 那时我还不是 Windows 程序员,但我怀疑它有这么多的历史。 Windows 有一堆 LPxyz 数据类型,可能是为了与这些名称保持一致。
    • @Todd:不。 Windows 开发人员认为他们必须为所有系统调用参数设置 SHOUTing 类型。
    • 回到16位8086,长(远)指针和短(近)指针是不一样的:前者是segment+offset的32位值,后者是16位偏移值(因此只能指向同一段内)。如今,长指针和任何其他类型的指针之间没有区别。
    • “长/短指针”具有误导性(“远/近”更清晰);它与指向的数据无关,而是指针表示。具有分段寻址的 16 位系统可以访问超过 2^16 字节的地址空间,但如果没有段前缀,则无法访问当前段之外的任何内容。 x86-32 和 x86-64 使用平面寻址(PAE 很奇怪,排序给你更长的物理地址,但虚拟地址仍然是 32 位),所以这不再相关,但命名是用 Win16 建立的。
    【解决方案3】:

    LPVOID 是

    typedef void* LPVOID
    

    Windef.h 中定义,其中定义了每个 Windows 数据类型。

    我们可以使用 void* 来指向任何类型。

    【讨论】:

      【解决方案4】:

      LPVOID 是指向任何类型的指针。 此类型在 WinDef.h 中声明如下: typedef void *LPVOID;

      【讨论】:

      • 只是好奇,您为什么要回答一个非常古老的问题,而答案比已经接受的答案信息量少得多?
      猜你喜欢
      • 2015-09-26
      • 2014-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多