我想要一个有关如何使用任意Win32 API编写VBA声明语句的通用指南。对于某些Win32 API(可能不包括我现在正在寻找的API或六个月后将要寻找的API),它不是声明语句的列表。
通用指南将教我如何处理不同的C / Win32数据类型。适用于32位或64位Office。
关于使VBA适应64位Office的主题告诉我,我可以使用LongPtr,并且32位或64位Office可以适当地对其进行适应。这仅在我知道32位何时需要Long时才有用。
这个VB.Net主题说不支持“任意”,但这是VB.Net,而不是VBA。我认为“任意”适用于VBA,但是什么时候使用呢?对于采用VOID或pVOID或LPVOID的API?
作为一个具体的例子,我需要修改这个声明:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSrc As Any, ByVal ByteLen As Long)
对于MSDN,最后一个参数是SIZE_T:
void CopyMemory(
_In_ PVOID Destination,
_In_ const VOID *Source,
_In_ SIZE_T Length
);
我已经看到64位Office的一些改编版本将其保留为声明,ByVal ... As Long
而其他人将其更改为LongPtr
。什么是正确的?
我不想挂在坏的内核调用上。
是否有通用指南可以弄清楚应如何处理Win32 API?
有关如何编写使用任意Win32 API的VBA声明语句的一般指南。
这就是我的方法。
我转到https://docs.microsoft.com/zh-cn/windows/win32/winprog/windows-data-types,找到我需要的数据类型(Ctrl+ F)。
如果是在同一页面上用另一种类型的术语定义的,那么我也要查找(Ctrl+ F),直到找到基本类型。
然后,我使用VB中适当大小的类型。int
是Long
,short
是Integer
,char*
是String
,wchar_t*
是LongPtr
,你需要传递StrPtr
,void*
是LongPtr
。
我认为“任意”仍然适用于VBA。但是什么时候使用呢?对于采用VOID的API?还是pVOID?或LPVOID?
As Any
当有帮助时
否则,As Any
使用API标头中指定的实际类型进行重新声明始终是可能,安全且正确的。通常,它是一个指针ByVal LongPtr
。
保持As Any
呼叫者承担更多责任,但给了他们更大的灵活性。重新声明As Any
为实际类型可以消除这种灵活性,但会降低灵活性。
CopyMemory
这是一个很好的例子。
的声明pDest As Any, pSrc As Any
最灵活,可以用作:
Dim a As Long, b As Long
CopyMemory a, b, ... ' Copying from variable b to a (a = b)
CopyMemory ByVal VarPtr(a), ByVal VarPtr(b), ... ' Same
Dim a As LongPtr, b As LongPtr
CopyMemory ByVal a, ByVal b, ... ' Copying from memory pointed to by b to memory pointed to by a
这很灵活,但是如果您滥用它:
Dim a As Long, b As Long
CopyMemory ByVal a, ByVal b, ... ' Wrong: passing values as pointers; likely memory access violation
CopyMemory VarPtr(a), VarPtr(b), ... ' Wrong: passing pointers to pointers;
' Overwrites the temporary storage VB provides
' No crash, but no meaningful copying either
Dim a As LongPtr, b As LongPtr
CopyMemory a, b, ... ' Likely wrong: copying the pointer value of b into a (a = b)
您可能会崩溃和/或破坏数据。
声明与相同的参数后ByVal pDest As LongPtr, ByVal pSrc As LongPtr
,您将失去传递Long
第一个示例中的ByRef的能力,并且VarPtr
每次都需要显式使用它,但是您不必考虑太多如何调用该函数。但是仍然存在一些危险,因为您仍然可以像CopyMemory a, b
使用Long
参数一样调用它,并且将值作为指针传递时会崩溃,但是至少您会从函数定义中看到正在传递错误的内容,而As Any
没有传递给您一个提示。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句