Win32API_PtrSafe.TXT: better version available? RRS feed

All replies

  • Erwin, what is the problem you are facing? 64 bit environment expects the Library functions used in your Project to be declared as PtrSafe. For example in my project I use Sleep prcedure, in a 32 bit environment I would be using.

    Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

    However in a 64-bit environment the code will be simply,

    Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

    All you have to do is simply replace all declaration to PtrSafe.

    Happy to help ! When you see answers and helpful posts, please click Vote As Helpful, Propose As Answer, and/or Mark As Answered

    Tuesday, March 18, 2014 1:24 PM
  • Simple example:

    Declare PtrSafe Function GetEnvironmentStrings Lib "kernel32" Alias "GetEnvironmentStringsA" () As String
    Sub test1()
       Dim s As String
       s = GetEnvironmentStrings
    End Sub

    I get "Microsoft Excel has stopped working". As mentioned I could work around this by using a LongPtr instead of a string (needed to update the call to CreateProcess accordingly to pass the LongPtr on).


    Tuesday, March 18, 2014 2:54 PM
  • Hi Erwin,

    Thanks for pointing out it.

    The return type of GetEnvironmentStrings Function is string array rather than string. When the block returned by GetEnvironmentStrings is no longer needed, it should be freed by calling the FreeEnvironmentStrings function.

    Below is a workaround for your reference, please let me know whether your issue is resolved.

    Declare PtrSafe Function GetEnvironmentStrings Lib "KERNEL32" Alias "GetEnvironmentStringsA" () As LongPtr
    Declare PtrSafe Function FreeEnvironmentStrings Lib "KERNEL32" Alias "FreeEnvironmentStringsA" (ByVal lpsz As LongPtr) As Long
    Declare PtrSafe Function lstrcpy Lib "kernel32.dll" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As Any) As Long
    Sub GetEnvWorkAround()
        Dim datEvBlock As LongPtr
        Dim Str As String
        Dim dl As Long, Offset As Long, i As Long
        Dim MyArray() As String
        i = 1
        Offset = 0
        Str = " "
        datEvBlock = GetEnvironmentStrings()
        Do While Len(Str) > 0
        Str = Space(255)
        dl = lstrcpy(Str, datEvBlock + Offset)
        Str = Trim(Str)
        Str = Left(Str, Len(Str) - 1)
        Offset = Len(Str) + Offset + 1
        ReDim Preserve MyArray(i)
        MyArray(i) = Str
        Debug.Print MyArray(i)
        i = i + 1
        dl = FreeEnvironmentStrings(datEvBlock)
    End Sub



    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Wednesday, March 19, 2014 6:57 AM
  • Thanks very much!

    To be complete, here is another problem I had:

    ' declarations from Win32API_PtrSafe.TXT
            cb As Long
            lpReserved As String
            lpDesktop As String
            lpTitle As String
            dwX As Long
            dwY As Long
            dwXSize As Long
            dwYSize As Long
            dwXCountChars As Long
            dwYCountChars As Long
            dwFillAttribute As Long
            dwFlags As Long
            wShowWindow As Integer
            cbReserved2 As Integer
            lpReserved2 As LongPtr
            hStdInput As LongPtr
            hStdOutput As LongPtr
            hStdError As LongPtr
    End Type
    Declare PtrSafe Sub GetStartupInfo Lib "kernel32" Alias "GetStartupInfoA" (lpStartupInfo As STARTUPINFO)
    Sub test3()
       Dim sui As STARTUPINFO
       sui.cb = Len(sui)
       Call GetStartupInfo(sui)
    End Sub

    This will crash Excel 64 bit. My work around: replace STRINGs in STARTUPINFO by LONGPTRs.

    Erwin Kalvelagen
    Amsterdam Optimization Modeling Group

    Wednesday, March 19, 2014 2:01 PM
  • This seems incorrect in Win32API_PtrSafe.txt:

    lCustData As LongPtr

    but the correct text should be

    lCustData As Long

    Note: lCustData is NOT a handle or a pointer

    Thursday, October 19, 2017 7:44 PM