mic*_*ael 15 macos winapi vba declare kernel32
在Windows上,声明的函数RtlMoveMemory提供了一种将字节块从一个地址复制到另一个地址的方法:
Private Declare PtrSafe Sub RtlMoveMemory Lib "kernel32" ( _
ByVal dest As LongPtr, _
ByVal src As LongPtr, _
ByVal size As LongPtr)
Run Code Online (Sandbox Code Playgroud)
Mac OS X上的等价物是什么?
Mac OS X上的等价物是什么?
简短回答:
Private Declare PtrSafe Function CopyMemory Lib "libc.dylib" Alias "memmove" _
( _
ByVal dest As LongPtr _
, ByVal src As LongPtr _
, ByVal size As LongLong _
) _
As LongPtr
Run Code Online (Sandbox Code Playgroud)
答案很长:取决于;)
以下是一个完全成熟的示例,它使用条件编译*使其可以在任何Mac/Windows/32位/ 64位计算机上运行.它还演示了声明和调用函数的两种不同方式(通过Pointer和Variable).
#If Mac Then
#If Win64 Then
Private Declare PtrSafe Function CopyMemory_byPtr Lib "libc.dylib" Alias "memmove" (ByVal dest As LongPtr, ByVal src As LongPtr, ByVal size As Long) As LongPtr
Private Declare PtrSafe Function CopyMemory_byVar Lib "libc.dylib" Alias "memmove" (ByRef dest As Any, ByRef src As Any, ByVal size As Long) As LongPtr
#Else
Private Declare Function CopyMemory_byPtr Lib "libc.dylib" Alias "memmove" (ByVal dest As Long, ByVal src As Long, ByVal size As Long) As Long
Private Declare Function CopyMemory_byVar Lib "libc.dylib" Alias "memmove" (ByRef dest As Any, ByRef src As Any, ByVal size As Long) As Long
#End If
#ElseIf VBA7 Then
#If Win64 Then
Private Declare PtrSafe Sub CopyMemory_byPtr Lib "kernel32" Alias "RtlMoveMemory" (ByVal dest As LongPtr, ByVal src As LongPtr, ByVal size As LongLong)
Private Declare PtrSafe Sub CopyMemory_byVar Lib "kernel32" Alias "RtlMoveMemory" (ByRef dest As Any, ByRef src As Any, ByVal size As LongLong)
#Else
Private Declare PtrSafe Sub CopyMemory_byPtr Lib "kernel32" Alias "RtlMoveMemory" (ByVal dest As LongPtr, ByVal src As LongPtr, ByVal size As Long)
Private Declare PtrSafe Sub CopyMemory_byVar Lib "kernel32" Alias "RtlMoveMemory" (ByRef dest As Any, ByRef src As Any, ByVal size As Long)
#End If
#Else
Private Declare Sub CopyMemory_byPtr Lib "kernel32" Alias "RtlMoveMemory" (ByVal dest As Long, ByVal src As Long, ByVal size As Long)
Private Declare Sub CopyMemory_byVar Lib "kernel32" Alias "RtlMoveMemory" (ByRef dest As Any, ByRef src As Any, ByVal size As Long)
#End If
Public Sub CopyMemoryTest()
Dim abytDest(0 To 11) As Byte
Dim abytSrc(0 To 11) As Byte
Dim ¡ As Long
For ¡ = LBound(abytSrc) To UBound(abytSrc)
abytSrc(¡) = AscB("A") + ¡
Next ¡
MsgBox "Dest before copy = #" & ToString(abytDest) & "#"
CopyMemory_byVar abytDest(0), abytSrc(0), 4
MsgBox "Dest during copy = #" & ToString(abytDest) & "#"
CopyMemory_byPtr VarPtr(abytDest(0)) + 4, VarPtr(abytSrc(0)) + 4, 4
MsgBox "Dest during copy = #" & ToString(abytDest) & "#"
CopyMemory_byPtr VarPtr(abytDest(8)), VarPtr(abytSrc(8)), 4
MsgBox "Dest after copy = #" & ToString(abytDest) & "#"
End Sub
Public Function ToString(ByRef pabytBuffer() As Byte) As String
Dim ¡ As Long
For ¡ = LBound(pabytBuffer) To UBound(pabytBuffer)
ToString = ToString & Chr$(pabytBuffer(¡))
Next ¡
End Function
Run Code Online (Sandbox Code Playgroud)
说明:
CopyMemory函数的Mac版本返回结果,而Win版本则不返回.(结果是dest指针,除非发生错误.请参阅此处的memmove参考.)但是,两个版本的使用方式完全相同,无括号.
声明的差异如下:
64位Mac/Win VBA7:
PtrSafe关键字Any对所有 ByRef参数使用类型LongPtr类型ByVal句柄/指针参数/返回值LongLong适当地使用该类型用于其他返回值/参数32位Win VBA7:
PtrSafe关键字Any对所有 ByRef参数使用类型LongPtr类型ByVal句柄/指针参数/返回值Long(非 LongLong)类型32位Mac/Win VBA6:
PtrSafe关键字Any对所有 ByRef参数使用类型Long类型ByVal句柄/指针参数/返回值Long适当地使用该类型用于其他返回值/参数注意事项:
在Windows Excel 2007 32位上测试.
似乎Excel 2007存在与双字对齐相关的问题.在这个例子中:
CopyMemory_byVar abytDest(0), abytSrc(0), 4 '-> ABCD
CopyMemory_byVar abytDest(1), abytSrc(1), 8 '-> ABCDEFGHI
CopyMemory() 跳过所有复制,直到达到双字对齐(在这种情况下为3次跳过),然后从第4个字节继续复制.
注意:如果您对我的变量命名约定感到好奇,那么它基于RVBA.
*在正确的道路.