Handling Pointers in LotusScript: 32-bit vs 64-bit

In LotusScript, developers can interface with native C APIs using callouts, allowing them to obtain and manipulate raw memory pointers. For example, the snippet below demonstrates how a developer might lock a memory handle, obtain the pointer, and traverse the memory block manually:
Dim ptr As Long
ptr = OSLockObject(handle_to_buffer)
Print ptr
ptr = ptr + 1  ' Move pointer forward (byte-wise traversal)
...
...
OSUnlockObject(handle_to_buffer)
This technique works reliably in 32-bit HCL Notes, but breaks in 64-bit HCL Notes due to fundamental architectural differences:
  • On 32-bit systems, both the Long data type and memory pointers are 4 bytes in size.
  • On 64-bit systems, memory pointers expand to 8 bytes, but the Long type in LotusScript remains 4 bytes.
  • LotusScript was not originally designed to accommodate 8-byte pointers, which leads to incorrect behavior or crashes.

Workaround: Using Double as a Pointer

To address this limitation, a practical workaround utilizes the Double data type, which is 8 bytes in size and natively available in LotusScript. Although Double is typically used for floating-point operations, it can be re-purposed to hold 64-bit pointer values.

To enable this functionality, the NotesSession class provides the UseDoubleAsPointer property. When set to True, it informs the LotusScript engine to treat Double variables as raw pointers:
Dim d As Double

session.UseDoubleAsPointer = True
' Use 'd' as a pointer
session.UseDoubleAsPointer = False
' Reverts 'd' to standard floating-point behavior

Pointer arithmetic in 64-bit systems

A subtle but critical issue arises when trying to perform pointer arithmetic using the Double type. Even though the value is stored as a pointer, it is still internally represented as a floating-point number. As a result, operations like ptr = ptr + 1 do not behave as expected—adding 1 to a floating-point number does not guarantee advancing to the next byte in memory.
session.UseDoubleAsPointer = True
Dim ptr As Double
ptr = OSLockObject(handle_to_buffer)  ' Value may appear like 2.751542356E+18
ptr = ptr + 1                         ' INCORRECT: Not valid pointer arithmetic
session.UseDoubleAsPointer = False

Correct Approach: AdjustPointer API

To safely perform pointer arithmetic in 64-bit LotusScript, use the AdjustPointer method provided by the NotesSession class. This method accepts a Double pointer and an offset (as Long) and adjusts the pointer accordingly, ensuring correct traversal behavior.

Syntax: NotesSession.AdjustPointer(pointer As Double, offset As Long)

Example:
session.UseDoubleAsPointer = True
Dim ptr As Double
ptr = OSLockObject(handle_to_buffer)

'Correct way to advance the pointer by a byte offset
session.AdjustPointer (ptr, CLng(offset))

session.UseDoubleAsPointer = False
Important: Always use CLng() to explicitly convert the offset to a Long. Passing a non-integer or incorrect data type may result in unexpected behavior or runtime errors.

By following these practices, developers can effectively manage raw memory pointers in 64-bit environments using LotusScript, ensuring compatibility and stability when working with the C API.