https://bugs.documentfoundation.org/show_bug.cgi?id=81123

--- Comment #4 from John Michelle <[email protected]> ---
(In reply to Anton Kochkov from comment #1)
> See short note about StrPtr:
> 
>     StrPtr is used primarily to make efficient UNICODE API calls. In VB4,
> API calls to a UNICODE function were made with the help of byte arrays:
> 
>        Declare Sub MyUnicodeCall Lib "MyUnicodeDll.Dll" _
>           (pStr As Byte)
> 
>        Sub MakeCall(MyStr As String)
>           Dim bTmp() As Byte
>           bTmp = MyStr & vbNullChar
>           MyUnicodeCall bTmp(0)
>           MyStr = bTmp
>           MyStr = Left$(MyStr, Len(MyStr - 1))
>        End Sub
> 
>     Clearly, the amount of work to simply pass a NULL terminated UNICODE
> string and return its value into the original string is totally
> unacceptable. By the time correct handling of the terminating NULL character
> is included, No less than 4 copies of the string are required.
> 
>     With StrPtr, this code reduces to:
> 
>        Declare Sub MyUnicodeCall Lib "MyUnicodeDll.Dll" _
>           (ByVal pStr As Long)
> 
>        Sub MakeCall(MyStr As String)
>           MyUnicodeCall StrPtr(MyStr)
>        End Sub
> 
>     VarPtr/StrPtr/ObjPtr are all very, very fast, so the overhead to call a
> UNICODE function is now actually lower than calling the corresponding ANSI
> function because no conversion is required.
> 
>     StrPtr can also be used to optimize ANSI declare calls. Instead of
> passing the same string variable multiple times to a declare function and
> incurring the conversion overhead for each call, use the StrConv function
> once and StrPtr in each call:
> 
>        Declare Sub MyAnsiCall Lib "MyAnsiDll.Dll" _
>           (ByVal pStr As String)
> 
>        MyAnsiCall MyStr
> 
>     becomes:
> 
>        Declare Sub MyAnsiCall Lib "MyAnsiDll.Dll" _
>           (ByVal pStr As Long)
> 
>        MyStr = StrConv(MyStr, vbFromUnicode)
>        MyAnsiCall StrPtr(MyStr)
>        MyStr = StrConv(MyStr, vbUnicode) ' Not always required
> 
>     StrPtr is also the only way to tell the different between an empty
> string ("") and a null string (vbNullString). StrPtr(vbNullString) returns
> 0, while StrPtr("") is non-zero.
> 
> From http://vb.mvps.org/tips/varptr.asp

This explanation really highlights why StrPtr was such a game-changer for VB
developers working with Unicode APIs. The old byte-array approach wasn’t just
verbose, it introduced unnecessary memory copies, performance overhead, and a
higher risk of subtle bugs around null-termination and string length handling.
Using StrPtr directly avoids all of that by passing a pointer to the internal
Unicode buffer, which is exactly what most Unicode APIs expect.

That said, one important thing for developers to remember is that StrPtr should
only be used when the API explicitly expects a pointer to a Unicode string and
does not attempt to reallocate or persist the pointer beyond the call. Since VB
strings are managed by the runtime, passing the pointer to APIs that modify
buffer size or store the pointer can lead to crashes or memory corruption.
Pairing StrPtr with proper ByVal declarations and understanding API ownership
rules is critical.

The same performance logic applies when optimizing ANSI calls — doing a single
StrConv and reusing StrPtr avoids repeated conversions and can significantly
reduce overhead in tight loops or high-frequency API calls. Topics like this
are a great reminder that understanding what’s happening under the hood often
matters more than just getting code to “work.” I’ve seen similar deep-dive
discussions around memory handling, performance trade-offs, and legacy language
interoperability explained clearly on https://zonelify.com/ which is helpful
when dealing with lower-level concepts like pointers and runtime behavior.

-- 
You are receiving this mail because:
You are the assignee for the bug.

Reply via email to