MS-Access / Getting Started

Using LongPtr Data Types

Before we update the Declare statement, let's recall what got us into this situation: lack of an official pointer data type and the subsequent overloading of Long to be the unofficial pointer data type. If Visual Basic had a pointer data type from the beginning, we could have written that Declare statement properly so that it runs correctly on both 32-bit and 64-bit versions of Visual Basic.

In Office 2010, Microsoft introduces a new data type for Visual Basic to fill this role as the official pointer data type-LongPtr. With 32-bit Visual Basic, LongPtr is a 32-bit quantity; and with 64-bit Microsoft Visual Basic for Applications (VBA), LongPtr is a 64-bit quantity.

Now, we can rewrite the previous Declare statement, which will work with both 32-bit and 64-bit Visual Basic, as follows:

Declare Function RegOpenKeyA Lib "advapi32.dll" _
  (ByVal Key As LongPtr, ByVal SubKey As String, _
    NewKey As LongPtr) As Long

You'll also need to update any Long sized pointers in User Defined Types (UDTs) that are passed to and from Declare procedures. Here's an example with the Windows process information structure:

Type PROCESS_INFORMATION
    hProcess As LongPtr
    hThread As LongPtr
    dwProcessId As Long
    dwThreadId As Long
End Type

You need to remember that all Windows handlers are pointers and therefore need to be accordingly increased in size in your code. You can use LongPtr to hold and pass handles.

Using PtrSafe Attributes

As you're following along, you might be noticing that we have another problem: How can Visual Basic tell if a Declare statement's parameters and return value have been properly updated to handle pointers and are safe to use with both 32-bit and 64-bit Visual Basic? The answer, of course, is that it cannot. There are many Declare statements that quite legitimately pass or return Long values that are not pointers.

To address this issue, Microsoft introduced a new attribute for Declare statements called PtrSafe. This attribute tells Visual Basic that the Declare statement you're writing is safe to run with both 32-bit and 64-bit Visual Basic and that all pointer-sized values are properly handled. Without the PtrSafe attribute, 64-bit Visual Basic does not compile Declare statements. To maintain backward compatibility, 32-bit Visual Basic continues to compile Declare statements without the PtrSafe attribute. So, using the example we've been working through previously, the Declare statement is as follows:

Declare PtrSafe Function RegOpenKeyA Lib "advapi32.dll" _
  (ByVal Key As LongPtr, ByVal SubKey As String, _
    NewKey As LongPtr) As Long

Microsoft recommends that all new Declare statements use LongPtr and PtrSafe.

[Previous] [Contents] [Next]