忽略16位内容,可以在32或64位Office主机上运行VBA。 64位Office只能在64位OS上运行,而32位Office可以在Windows / macOS /其他操作系统的32位或64位版本上运行。
从VBA7开始,我们具有LongPtr
类型,在32位Office(Long
)上变为#Win64 = False
,在64位Office({ {1}}),与操作系统无关
我的问题: 在处理指针(内存中的地址)的API中,操作系统的位无关紧要,还是仅仅是运行我们关心的代码(32/64位Office主机/ VBA)?
一方面,我明白了为什么没关系:
LongLong
-#Win64 = True
为我们提供此指针)Long
-LongPtr
给出了这一点)LongLong
准确地表示了我的代码自己的内存的指针,而不考虑操作系统的位数但是我可以想象操作系统的重要性
LongPtr
类型的求值结果为LongPtr
,并且太短了表示该操作系统中可用的最大指针大小。LongPtr
类型实际上是错误的长度,用来表示指向VBA自身地址空间之外的内存中地址的指针!现在可能会出现问题,具体取决于操作系统位数而不是Office / VBA位数。如果我们在32位OS上运行VBA7,那么Long
将是您想要扔给它的任何内存块的正确长度;在99.9%的情况下,它是一种合适的指针数据类型,因为操作系统所做的一切都是32位(忽略16位)。
但是,当尝试使用LongPtr
来保存32位地址时,在32位VBA7代码上运行而不是在64位OS上运行会遇到困难。我觉得在64位操作系统上混合使用32位和64位应用程序非常普遍,因此这可能是一个现实问题。
只有在没有LongPtr
的帮助下,运行于32位和64位操作系统上的32位VBA6和更早的应用程序可能会遇到类似的问题。
现在,我意识到这是一个非常虚构的情况,谁愿意访问另一个应用程序的内存,对吗?实际上,它是如此人为设计,以至于我不确定我是否能想到一个重要而值得担心的情况。一个应用程序能否获得到另一个具有不同位数的应用程序的内存地址?也许有一些读写保护措施可以防止这种情况。
也许访问另一个应用程序的窗口句柄就是这种情况。那是公共内存,也许窗口句柄的位数反映了应用程序或操作系统的位数,在这种情况下,我的32位VBA希望保留对64位{{1}的引用},我不确定...
PS我知道,除了指针长度以外,在某些情况下OS位可能很重要。我知道一个; LongPtr
函数在64位和32位Windows上需要不同的声明-尽管IIUC已通过LongPtr
函数解决了,这两种函数是相同的。但是,任何其他类似的怪癖都将是有用的,我在这里只关注指针长度,因为我有一个需要特定信息的问题。
PPS想到了这一点,您甚至可以在编译时获得OS位。我认为您可以从Hwnd
推论得出,ofc SetWindowLong
表示64位Office和事实上的64位OS。但是我不确定是否有办法判断32位VBA是否在64位Windows上运行...
答案 0 :(得分:3)
当然,操作系统的重要性很重要。
在我们需要在64位Windows上为32位办公室使用特定代码(正确注册COM DLL以在32位应用程序中使用)的情况下,您可以看到this answer。
我使用的测试是:
#If Win64 Then
Const Win64 = True
#Else
Const Win64 = False
#End If
If Not Win64 And Environ$("ProgramW6432") <> vbNullString Then
'32 bits Office on Win 64
Else
'Either 32-bits Windows, or 64-bits Office on 64-bits windows
End If
Afaik,您无法在编译时确定它,只能在运行时确定。
使用外部API /应用程序时,这通常很重要。我将不编译可能出现的情况的列表,因为它永远不会完整,但是有很多可能的情况。
但是,对于内存访问来说,这没关系,因为访问另一个进程的非全局内存会引发段错误并使应用程序硬崩溃。而且,如果您使用的是全局变量,那不是真正的问题。
答案 1 :(得分:2)
对于您的流程,LongPtr
始终是正确的 。您无需担心其大小。您不需要WIN64
常量即可使用它。实际上,通常您唯一需要的常量是VBA7
,它告诉您LongPtr
是否可用。如果是,请使用它;如果不是,请使用x {1}}。
此外,Windows x64具有称为WoW64的整个兼容性层。作为在64位Windows上运行的32位应用程序,您不会注意到任何东西,并且就像操作系统是32位一样运行。指针大小为4个字节,指针大小的数据类型(例如Long
为4个字节),因此,再次声明,如果只咨询HWND
并正确放置,则无需担心任何这些问题。 VBA7
在必须出现指针大小的参数的所有位置。
因此,对于过程中的例行事务以及与OS及其对象的交互,您不必担心 自己或OS的麻烦,而您不必担心也不需要LongPtr
常量。
现在,您特别提到获得和使用对具有与您自己不同的位的进程有效的指针。是的,这可能是一个问题,但这不是VBA特有的问题。
如果作为VBA应用程序,您发现自己需要读取任意位数的任意进程的内存,则需要将自己的位数与其位数进行比较。此时,您可以 使用WIN64
常量,但是在这种情况下,在运行时检查WIN64
比使用单独的代码分支要方便得多。
进行了测试
但是请注意,即使在这种情况下,您也不在乎操作系统的位数或Len(long_ptr_variable)
const!您只关心自己的进程位和其他进程位。