LongPtr

A signed integer as wide as a pointer: a Long in a 32-bit build and a LongLong in a 64-bit build.

Syntax:

  • Dim varname As LongPtr [ = expression ]
  • DefLngPtr letterrange

A LongPtr variable is declared As LongPtr. DefLngPtr makes LongPtr the default type of the variables, parameters and functions whose names start with the letters in letterrange. LongPtr has no type-declaration character. A LongPtr that is not given a value holds 0.

Use LongPtr for pointers and handles: window handles, memory addresses, and the parameters and results of API functions that take them. The same source then builds for 32-bit and 64-bit targets.

Storage and range

A LongPtr is 4 bytes in a 32-bit build, with the range of a Long, and 8 bytes in a 64-bit build, with the range of a LongLong. It is not a type of its own at run time: TypeName gives Long in a 32-bit build and LongLong in a 64-bit one, and VarType gives vbLong (3) or vbLongLong (20). There is no vbLongPtr constant. A Variant that holds a LongPtr holds a Long or a LongLong.

The constant vbPtrSize is the size of a pointer in the build, 4 or 8, and VarPtr, StrPtr and ObjPtr return a LongPtr.

Dim Ptr As LongPtr
Dim Value As Long = 42
Debug.Print Ptr                     ' 0
Debug.Print LenB(Ptr) = vbPtrSize   ' True
Debug.Print TypeName(Ptr) = IIf(vbPtrSize = 8, "LongLong", "Long") ' True
Ptr = VarPtr(Value)
Debug.Print Ptr <> 0                ' True

Literals

There is no LongPtr literal and no type-declaration character. Assign a number or the result of a pointer function, or convert with CLngPtr: Dim Ptr As LongPtr = 5.

Conversions

CLngPtr converts an expression to a LongPtr, and so does assigning one to a LongPtr variable. A value outside the range raises error 6, Overflow, and the range depends on the build: CLngPtr(2147483648#) raises it in a 32-bit build and returns 2,147,483,648 in a 64-bit one.

A LongPtr variable assigned to a Long variable, as Size = Ptr, compiles in a 32-bit build and is refused in a 64-bit build with TB5001, because a LongLong does not narrow implicitly to a Long. Write CLng(Ptr) where a 32-bit value is wanted, which raises error 6 in a 64-bit build when the address does not fit.

Arithmetic

Arithmetic on a LongPtr follows the type it stands for in the build: Long in a 32-bit build and LongLong in a 64-bit one. Adding a Long to a LongPtr gives a LongPtr, so Ptr + 4 can step a pointer by 4 bytes, and a result that does not fit raises error 6. See Result types and promotion.

LongPtr in Declare statements

A Declare statement that is to work in both builds is written with the PtrSafe keyword, and declares every pointer and handle As LongPtr, as the example below does.

Note

VB6 has no LongPtr: a VB6 Declare passes handles and pointers as Long.

Example

This example declares a Win32 function that returns the handle of a window, and the one that copies memory. The same code builds for 32-bit and 64-bit: the handle and the address are LongPtr, and the length is the pointer-sized SIZE_T.

Private Declare PtrSafe Function GetForegroundWindow Lib "user32" () As LongPtr
Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
    (ByVal Destination As LongPtr, ByVal Source As LongPtr, ByVal Length As LongPtr)

Public Function CopyLong(ByVal Source As Long) As Long
    CopyMemory VarPtr(CopyLong), VarPtr(Source), LenB(Source)
End Function

Public Function IsAnyWindowActive() As Boolean
    IsAnyWindowActive = GetForegroundWindow() <> 0
End Function

See Also