vba - VBA 32 位和 64 位类型不匹配
问题描述
已更新请参阅问题的最后部分以获取更新
完整的源代码在这里:
https://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=30761&lngWId=1
我有一段代码不起作用,可能是由于 32 位和 64 位的差异:
部分代码:(我添加了 PtrSafe,我不应该为第一个添加)
Private Declare PtrSafe Function ArrPtr& Lib "msvbvm60.dll" Alias "VarPtr" (ptr() As Any)
Private Declare PtrSafe Sub RtlMoveMemory Lib "kernel32" (dst As Any, src As Any, ByVal nBytes&)
Private Header1(5) As Long
Private Header2(5) As Long
Private SafeArray1() As Integer
Private SafeArray2() As Integer
Private LUT(8482) As Long
Private Sub Class_Initialize()
Dim i As Long
' Set up our template for looking at strings
Header1(0) = 1 ' Number of dimensions
Header1(1) = 2 ' Bytes per element (integer = 2)
Header1(4) = &H7FFFFFFF ' Array size, 2.1+ billion should cover us
' Force SafeArray1 to use Header1 as its own header
RtlMoveMemory ByVal ArrPtr(SafeArray1), VarPtr(Header1(0)), 4
我搜索了一段时间,发现 msvbvm60.dll 似乎是旧的 32 位 VBA,已被 VBA7.dll 取代。尝试重新注册文件,因为它在 SysWOW64 文件夹中,之后 VBE 仍然报告找不到该文件。所以我注释了第一行,并将最后一行更改为:
RtlMoveMemory ByVal VarPtr(SafeArray1), VarPtr(Header1(0)), 4
我相信 ArrPtr 只是带有别名的 VarPtr。
现在我收到类型不匹配错误。我的理解是代码将 SafeArray1 的标头指向 Header1(0) 的地址。我假设这意味着 SafeArray1[0]~SafeArray[9] 应该包含 Header1(0)~Header1(4) 中的信息,因为 Header1() 是 Long 而 SafeArray() 是 Integer?但是 VarPtr 不应该在 32 位 Office 中返回 Long 吗?怎么可能在 Integer 数组上使用它?
但关键是如何让它在 64 位 Office 上运行。由于 VarPtr 现在返回 LongPtr 而不是 Long,我不确定如何修改代码。
更新 我发现了另一段代码,它给了我指向数组的指针:
Private Declare PtrSafe Function VarPtrArray Lib "VBE7" Alias _
"VarPtr" (ByRef Var() As Any) As LongPtr
然后我写了一个测试模块:
Private Declare PtrSafe Function VarPtrArray Lib "VBE7" Alias _
"VarPtr" (ByRef Var() As Any) As LongPtr
Private Declare PtrSafe Sub RtlMoveMemory Lib "kernel32" (dst As Any, src As Any, ByVal nBytes&)
Private Header1(5) As Long
Private SafeArray1() As Integer
Sub test()
Header1(0) = 1 ' Number of dimensions
Header1(1) = 2 ' Bytes per element (integer = 2)
Header1(4) = &H7FFFFFFF ' Array size, 2.1+ billion should cover us
RtlMoveMemory ByVal VarPtrArray(SafeArray1), VarPtr(Header1(0)), 4
Debug.Print SafeArray1(0)
End Sub
但是 VBE 在 RtlMoveMemory 行上崩溃。
解决方案
以下示例应显示如何处理Declare
32 位和 64 位版本的语句:
Option Explicit
#If VBA7 Then '64 bit
Private Declare PtrSafe Function DrawMenuBar Lib "User32" (ByVal hwnd As LongPtr) As LongPtr
#Else '32 bit
Private Declare Function DrawMenuBar Lib "User32" (ByVal hwnd As Long) As Long
#End If
推荐阅读
- google-chrome - 在 Chrome 扩展程序中访问 Google API - 我是否需要在清单中的权限中设置 URL?
- asp.net - 重定向到 Default.aspx 而不是在异常时设置错误 500 页面
- python - 在单个 JSON 中保存多个请求
- android - CollectionReference中的android firebase服务器时间戳
- python - 从 Ignition 中的串行读取十六进制或十进制
- javascript - For loop let scope stackblitz vs chrome dev tools
- ios - 是否有预设的“索引”或类似的东西可以让我引用用户创建的特定注释?斯威夫特 4
- r - highcharter 工具提示的附加数据
- android - 关于android上发布通知的编码问题
- html - 我的 index.html 文件应该是文本文件吗?