HttpOpenRequest() 中的 WinInet 访问冲突
WinInet Access Violation in HttpOpenRequest()
我正在尝试使用 WinInet 将文件上传到 PHP 页面。我在其中一个函数上遇到访问冲突,但不明白为什么。我从示例页面构建了代码。
代码如下:
HINTERNET aInternet=InternetOpen("My-Custom-Agent/1.0",INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,0);
HINTERNET aConnect=InternetConnect(aInternet,"www.myserver.com",INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
if (aConnect)
{
HINTERNET aRequest=HttpOpenRequest(aConnect, (const char*)"POST","myphppage.php", NULL, NULL, (const char**)"*/*[=10=]",0,1);
// ^^
// Exception happens on this line
// Exception thrown at 0x70C85B7C (ininet.dll) in TestApp.exe:
// 0xC00000005: Access violation reading location 0x002A2F2A
//
}
当我使用 InternetOpenURL()
从服务器下载时,一切似乎都很好。它只是不喜欢我在这里某处所做的事情。知道我做错了什么吗?
根据 HttpOpenRequest()
documentation:
[in] lplpszAcceptTypes
A pointer to a null-terminated array of strings that indicates media types accepted by the client. Here is an example.
PCTSTR rgpszAcceptTypes[] = {_T("text/*"), NULL};
Failing to properly terminate the array with a NULL pointer will cause a crash.
您传递的指针指向单个以 null 结尾的字符串,错误地类型转换为 const char**
:
lplpszAcceptTypes -> "*/*"
但是该函数需要一个指向 数组的指针 指针指向以 null 结尾的字符串,其中数组中的最后一个元素必须为 NULL 才能终止数组(因为有没有函数参数来指定数组中元素的数量):
-----
lplpszAcceptTypes -> | 0 | -> "*/*"
|---|
| 1 | -> NULL
-----
看出区别了吗?
该函数将字符串文字的 content 误解为指针,但事实并非如此,因此导致 AV 崩溃。出现 AV 的地址 0x002A2F2A
与字符串文字的内容字节相同 ("*/*“
= 0x2A 0x2F 0x2A 0x00
).
你需要改用这个:
LPCSTR rgpszAcceptTypes[] = {"*/*", NULL};
HINTERNET aRequest = HttpOpenRequest(aConnect, "POST", "myphppage.php", NULL, NULL, rgpszAcceptTypes, 0, 1);
我正在尝试使用 WinInet 将文件上传到 PHP 页面。我在其中一个函数上遇到访问冲突,但不明白为什么。我从示例页面构建了代码。
代码如下:
HINTERNET aInternet=InternetOpen("My-Custom-Agent/1.0",INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,0);
HINTERNET aConnect=InternetConnect(aInternet,"www.myserver.com",INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
if (aConnect)
{
HINTERNET aRequest=HttpOpenRequest(aConnect, (const char*)"POST","myphppage.php", NULL, NULL, (const char**)"*/*[=10=]",0,1);
// ^^
// Exception happens on this line
// Exception thrown at 0x70C85B7C (ininet.dll) in TestApp.exe:
// 0xC00000005: Access violation reading location 0x002A2F2A
//
}
当我使用 InternetOpenURL()
从服务器下载时,一切似乎都很好。它只是不喜欢我在这里某处所做的事情。知道我做错了什么吗?
根据 HttpOpenRequest()
documentation:
[in] lplpszAcceptTypes
A pointer to a null-terminated array of strings that indicates media types accepted by the client. Here is an example.
PCTSTR rgpszAcceptTypes[] = {_T("text/*"), NULL};
Failing to properly terminate the array with a NULL pointer will cause a crash.
您传递的指针指向单个以 null 结尾的字符串,错误地类型转换为 const char**
:
lplpszAcceptTypes -> "*/*"
但是该函数需要一个指向 数组的指针 指针指向以 null 结尾的字符串,其中数组中的最后一个元素必须为 NULL 才能终止数组(因为有没有函数参数来指定数组中元素的数量):
-----
lplpszAcceptTypes -> | 0 | -> "*/*"
|---|
| 1 | -> NULL
-----
看出区别了吗?
该函数将字符串文字的 content 误解为指针,但事实并非如此,因此导致 AV 崩溃。出现 AV 的地址 0x002A2F2A
与字符串文字的内容字节相同 ("*/*“
= 0x2A 0x2F 0x2A 0x00
).
你需要改用这个:
LPCSTR rgpszAcceptTypes[] = {"*/*", NULL};
HINTERNET aRequest = HttpOpenRequest(aConnect, "POST", "myphppage.php", NULL, NULL, rgpszAcceptTypes, 0, 1);