操作系统的位数是否重要,还是只是我需要担心的应用程序? [英] Does the bitness of the OS ever matter, or is it just the application I need to worry about?

查看:18
本文介绍了操作系统的位数是否重要,还是只是我需要担心的应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

忽略 16 位的东西,VBA 可以在 32 位或 64 位的 Office 主机上运行.64 位 Office 只能在 64 位操作系统上运行,而您可以在 32 64 位版本的 Windows/macOS/其他操作系统上运行 32 位 Office.

Ignoring 16-bit stuff, VBA can be run on 32 or 64-bit Office hosts. 64-bit Office can only be run on a 64-bit OS, whereas you can run 32-Bit office on a 32 or 64-bit version of Windows/macOS/other Operating System.

从 VBA7 开始,我们有 LongPtr 类型,它在 32 位 Office 上变成了 Long (#Win64 = False),LongLong 在 64 位 Office (#Win64 = True) 上,不管操作系统位数

As of VBA7, we have the LongPtr type, which becomes a Long on 32-bit Office (#Win64 = False), LongLong on 64-bit Office (#Win64 = True), regardless of the OS bitness

我的问题:在处理指针(内存中的地址)的 API 中,操作系统位数是否重要,还是只有运行我们关心的代码的应用程序(32/64 位 Office 主机/VBA)?

My question: In APIs that deal with pointers (addresses in memory), does the OS bitness ever matter, or is it only the application running the code that we care about (32/64-bit Office host/VBA)?

一方面,我明白为什么这可能无关紧要:

On the one hand I can see why it might not matter:

  • 在 32 位 Excel 中运行的 VBA 将具有 32 位地址空间(与操作系统无关)
  • 因此任何指向它自己的内存的指针都应该是 32 位的(即 Longs - LongPtr 给我们这个)
  • 类似的 64 位 VBA(必须在 64 位操作系统中,但实际上可以在任何地方)有一个 64 位地址空间(每个指针本身是 64 位长,指的是一个 64 位宽的内存块)
  • 因此任何指向其自身内存的指针都应该是 64 位(即 LongLongs - LongPtr 给我们这个)
  • 所以 LongPtr 准确地表示一个指向我的代码自己的内存的指针,而不管操作系统的位数
  • VBA running in 32-bit Excel will have a 32-bit address space (regardless of OS)
  • Therefore any pointers to its own memory should be 32-bits (i.e. Longs - LongPtr gives us this)
  • Similarly 64-bit VBA (necessarily in 64-bit OS, but really could be anywhere) has a 64 bit address space (each pointer is itself 64-bits long and refers to a 64-bit wide block of memory)
  • Therefore any pointers to its own memory should be 64-bits (i.e. LongLongs - LongPtr gives us this)
  • So LongPtr accurately represents a pointer to my code's own memory, regardless of OS bitness

但是我可以想象操作系统位数可能很重要

However I can imagine times where the OS bitness could matter

  • 在 64 位操作系统上运行 32 位 VBA,但想要引用不同 64 位应用程序的内存区域,LongPtr 类型将评估为 Long 并且太短而无法表示该操作系统中可用的最大指针大小.
  • 类似地,访问 32 位应用程序内存的 64 位 VBA 会发现其指针类型太大而无法容纳地址
  • 现在备受信赖的LongPtr类型实际上是错误的长度来表示指向VBA自身地址空间之外的内存地址的指针!
  • Running 32-bit VBA on 64-bit OS, but wanting to refer to areas in memory of a different 64-bit application, the LongPtr type would evaluate to Long and would be too short to represent the maximum pointer size available in that OS.
  • Similarly a 64-bit VBA accessing memory of a 32-bit application would find its pointer type too large to hold the address
  • Now the much trusted LongPtr type is actually the wrong length to represent a pointer to an address in memory outside VBA's own address space!

现在可能会出现问题,具体取决于操作系统位数,而不是 Office/VBA 位数.如果我们在 32 位操作系统上运行 VBA7,那么 LongPtr 将是您想要扔给它的任何内存块的正确长度;它在 99.9% 的情况下都是合适的指针数据类型,因为操作系统所做的一切都是 32 位(忽略 16 位).

Problems can now arise depending on OS bitness, not Office/VBA bitness. If we're running VBA7 on 32-bit OS, then LongPtr will be the right length for any chunk of memory you could want to throw at it; it is a suitable pointer datatype in 99.9% of cases since everything the OS does is 32-bit (ignoring 16 bit).

然而,在尝试使用 LongPtr 保存 32 位地址时,相同的 32 位 VBA7 代码而不是在 64 位操作系统上运行会遇到困难.我觉得在 64 位操作系统上混合 32 位和 64 位应用程序很常见,所以这可能是一个真正的问题.

However the same 32-bit VBA7 code instead running on a 64-bit OS would run into difficulties when trying to use LongPtr to hold 32-bit addresses. I feel it's quite common to mix 32-bit and 64-bit applications on a 64-bit OS so this could be a real issue.

在 32 位和 64 位操作系统上运行的 32 位 VBA6 和更早的应用程序可能会面临类似的问题,只有在没有 LongPtr

32-bit VBA6 and earlier applications running on 32 vs 64 bit Operating Systems could face similar issues, only without the help of LongPtr

现在我意识到这是一个非常人为的情况,谁会想要访问另一个应用程序的内存,对吗?事实上,它是如此人为,以至于我不确定我是否能想出一个重要且值得担心的情况.一个应用程序能否获得另一个具有不同位元的应用程序的内存地址?也许有一些读写保护可以防止这种情况发生.

Now I appreciate that's a pretty contrived situation, who would ever want to access another application's memory, right? In fact it's so contrived that I'm not sure I could ever come up with a situation where this is important and worth worrying about. Could an application ever obtain an address to the memory of another application with different bitness? Maybe there are some read-write protections preventing this.

也许访问另一个应用程序的窗口句柄就是这样一种情况;那是公共内存,也许窗口句柄的位数反映了应用程序或操作系统的位数,在这种情况下,我的 32 位 VBA 想要保存对 64 位 Hwnd 的引用是可行的,我不确定...

Perhaps accessing another application's window handle would be one such occasion; that's public memory and perhaps the bitness of the window handle reflects the bitness of the application or the Operating system, in which case it would be feasible for my 32-bit VBA to want to hold a reference to a 64-bit Hwnd, I'm not sure...

PS 我知道除了指针长度之外,还有其他情况下操作系统位数可能很重要.我知道一个;SetWindowLong 函数在 64 位和 32 位 Windows 上需要不同的声明 - 尽管现在使用 SetWindowLongPtr 函数解决了 IIUC,这对两者都是相同的.但是,了解任何其他类似的怪癖都会很有用,我在这里只关注指针长度,因为我有一个需要该特定信息的问题.

PS I'm aware there are situations other than pointer length where OS bitness may be important. I know of one; the SetWindowLong function required different declarations on 64-bit vs 32-bit Windows - although IIUC that's now been solved with the SetWindowLongPtr function which is identical for both. But any other similar quirks would be useful to know about, I'm only focussing on pointer length here because I have a problem that requires that specific info.

PPS 想一想,你能不能在编译时得到 OS bitness;我认为你可以从 MAC_OFFICE_VERSION 推断出来,ofc Win64 = True 表示 64 位 Office 和事实上的 64 位操作系统.但我不确定是否有办法判断 32 位 VBA 是否在 64 位 Windows 上运行...

PPS come to think of it, can you even get OS bitness at compile time; I think you can infer it from MAC_OFFICE_VERSION, and ofc Win64 = True means 64-bit Office and de-facto 64-bit OS. But I'm not sure if there's a way to tell whether 32-bit VBA is running on 64-bit Windows...

推荐答案

LongPtr 对于您的流程来说总是正确的.您无需担心它的大小.您不需要 WIN64 常量即可使用它.事实上,您通常需要的唯一常量是VBA7,它告诉您LongPtr 是否可用.如果是,使用它,如果不是,你肯定是 x86 所以使用 Long.

A LongPtr is always correct for your process. You do not need to worry about its size. You do not need the WIN64 constant to use it. In fact, the only constant you normally need is VBA7 that tells you whether the LongPtr is even available. If it is, use it, if it's not, you are definitely x86 so use Long.

此外,Windows x64 有一个完整的兼容层,称为 WoW64.作为在 64 位 Windows 上运行的 32 位应用程序,您不会注意到任何事情,并且运行时就像操作系统是 32 位一样.你的指针大小是四个字节,你的指针大小的数据类型如 HWNDs 是四个字节,所以同样,如果你只参考 VBA7 并正确地将 LongPtr 放在必须出现指针大小参数的所有位置.

Additionally, Windows x64 has an entire compatibility layer called WoW64. As a 32-bit app running on 64-bit Windows, you do not notice anything and you run as if the OS was 32-bit. Your pointer size is four bytes, your pointer-sized data types such as HWNDs are four bytes, so again, you do not need to worry about any of that if you only consult VBA7 and correctly place LongPtr in all places where a pointer-sized argument must appear.

因此,对于进程中的日常事务,以及与操作系统及其对象的交互,您无需担心您自己的或操作系统的位数,而且您无需担心也不需要 WIN64 常量.

So, for routine things inside your process, and for interacting with the OS and its objects, you don't need to worry about either your own or the OS'es bitness, and you don't need the WIN64 constant either.

现在,您特别提到了获取和使用对与您自己的位数不同的进程有效的指针.是的,这可能是一个问题,但这个问题不是 VBA 特有的.

Now, you specifically mention obtaining and using pointers that are valid for processes with different bitness than your own. Yes, that might be a problem, but this problem is not specific to VBA.

如果作为 VBA 应用程序,您发现自己需要读取任意位数的任意进程的内存,您确实需要将自己的位数与其位数进行比较.在这一点上,您可以使用WIN64常量,但在这种情况下,在运行时检查Len(long_ptr_variable)要方便得多而不是拥有单独的代码分支.

If, as a VBA app, you find yourself in a need to read memory of an arbitrary process of arbitrary bitness, you do need to compare your own bitness to its bitness. At this point you could make use of the WIN64 constant, but it's much more convenient in this case to check the Len(long_ptr_variable) at runtime than to have separate code branches.

经过测试,

  • 如果您的位数更高,您可以不受限制地读取其他进程的内存.
  • 如果您的位数较小,您可以在 4 字节指针允许的范围内尽可能多地到达大家伙的虚拟内存.
    • 如果您需要超越这一点,您将不得不失败(或不).

    但请注意,即使在这种情况下,您也不关心操作系统位数或 WIN64 常量!您只关心您的进程位数与其他进程位数.

    But note that even in this case, you don't care about the OS bitness or the WIN64 const either! You only care about your process bitness vs the other process bitness.

    这篇关于操作系统的位数是否重要,还是只是我需要担心的应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆