如何使 WinHttpCrackUrl 在 64 位下工作 [英] How to make WinHttpCrackUrl work in 64-bit

查看:36
本文介绍了如何使 WinHttpCrackUrl 在 64 位下工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有使用 WinHttp 的 Visual Basic for Applications 代码,并且可以与在 32 位 Windows XP 上运行的 32 位 Office 2010 完美配合.相同的代码无法在 64 位 Windows 8 上的 64 位 Office 2013 上正常运行,即使它编译正常.

I have Visual Basic for Applications code that uses WinHttp and works flawlessly with 32-bit Office 2010 running on 32-bit Windows XP. The same code fails to run properly on 64-bit Office 2013 on 64-bit Windows 8, even though it compiles fine.

问题是 WinHttpCrackUrl() 在 Windows 8 上返回错误 87参数不正确".

The problem is that WinHttpCrackUrl() returns an error 87 "The parameter is incorrect" on Windows 8.

我已经双重检查和三重检查所有指针都在代码中适当地声明为 LongPtr.我做错了什么?

I have double-checked and triple-checked that all pointers are declared as LongPtr in the code where appropriate. What am I doing wrong?

以下代码在 32 位 Excel/Windows 上运行良好,但在 64 位 Excel/Windows 上无法运行:

Here is the code that runs fine on 32-bit Excel/Windows, but fails to run on 64-bit Excel/Windows:

Private Type URL_COMPONENTS
    dwStructSize      As Long
    lpszScheme        As LongPtr
    dwSchemeLength    As Long
    nScheme           As Long
    lpszHostName      As LongPtr
    dwHostNameLength  As Long
    nPort             As Long
    lpszUserName      As LongPtr
    dwUserNameLength  As Long
    lpszPassword      As LongPtr
    dwPasswordLength  As Long
    lpszUrlPath       As LongPtr
    dwUrlPathLength   As Long
    lpszExtraInfo     As LongPtr
    dwExtraInfoLength As Long
End Type

Private Declare PtrSafe Function WinHttpCrackUrl Lib "WinHTTP" ( _
    ByVal pwszUrl As LongPtr, _
    ByVal dwUrlLength As Long, _
    ByVal dwFlags As Long, _
    ByRef lpUrlComponents As URL_COMPONENTS) As Long

Sub Test()
    Dim result as Long
    Dim URLComp As URL_COMPONENTS
    Dim mURL as String
    mURL = "http://www.stackoverflow.com" & vbNullChar

    With URLComp
        .dwStructSize = Len(URLComp)
        .dwHostNameLength = -1
        .dwSchemeLength = -1
        .dwUrlPathLength = -1
    End With

    result = WinHttpCrackUrl(StrPtr(mURL), 0, 0, URLComp)

    ' Prints 1 on 32-bit Excel/Windows (indicating success)
    ' Prints 0 on 64-bit Excel/Windows (indicating failure)
    Debug.Print result

    ' Prints 87 on 64-bit Excel/Windows ("The parameter is incorrect.")
    Debug.Print err.LastDllError
End Sub

推荐答案

struct 在 C++ 代码中是对齐的,但 VBA 结构是压缩的.在 32 位中,对于您的结构,这无关紧要,因为所有成员都对齐 4.但在 64 位中,指针需要 8 字节对齐,并且结构有一些额外的填充.像这样输入:

The struct is aligned in the C++ code, but VBA structs are packed. In 32 bit, for your struct, it does not matter since all members have alignment 4. But in 64 bit the pointers need 8 byte alignment and the struct has some extra padding. Put it in like this:

Private Type URL_COMPONENTS
    dwStructSize      As Long
    padding1          As Long
    lpszScheme        As LongPtr
    dwSchemeLength    As Long
    nScheme           As Long
    lpszHostName      As LongPtr
    dwHostNameLength  As Long
    nPort             As Long
    lpszUserName      As LongPtr
    dwUserNameLength  As Long
    padding2          As Long
    lpszPassword      As LongPtr
    dwPasswordLength  As Long
    padding3          As Long
    lpszUrlPath       As LongPtr
    dwUrlPathLength   As Long
    padding4          As Long
    lpszExtraInfo     As LongPtr
    dwExtraInfoLength As Long
    padding5          As Long
End Type

我想你会想要一些条件编译来切换更好的 32 位和 64 位版本,但我必须承认我不知道如何用 VBA 做到这一点.

I guess you'll want some conditional compilation to switch better 32 and 64 bit versions but I must confess to having no idea how to do that with VBA.

这篇关于如何使 WinHttpCrackUrl 在 64 位下工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆