调用函数三次后可执行文件崩溃

时间:2015-07-21 04:19:09

标签: c++ mingw stringstream

我想知道我对C ++比较陌生(并且在同一天询问有关同一项目的两个问题时感到有点内疚)。

运行下面的循环(或取消注释调用MyDownloadFunction然后运行的五个连续行)将导致应用程序崩溃。

错误讯息:
terminate called after throwing an instance of 'std::ios_base::failure' what(): basic_ios::clear This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information.

我想知道的是,如果只调用一次或两次函数它不会崩溃,但如果它运行3次或更多次会崩溃(并且第三次,文件崩溃)保存得当,当然还有如何修复它。

请假设此问题存在https://MyWebsite.com

#include <iostream>
#include <sstream>
// #include <stdio.h>
// #include <string>
#include <windows.h>

using namespace std;

int main() {
    typedef int * (*MyDownloadToUrl)(void*, const char*, const char*, DWORD, void*);
    HINSTANCE LibHnd = LoadLibrary("Urlmon.dll");
    MyDownloadToUrl MyDownloadFunction = (MyDownloadToUrl)GetProcAddress(LibHnd,"URLDownloadToFileA");

    stringstream URL;
    stringstream Iteration;

    // MyDownloadFunction(NULL, "https://google.ca", "Google 1.htm", 0, NULL);
    // MyDownloadFunction(NULL, "https://google.ca", "Google 2.htm", 0, NULL);
    // MyDownloadFunction(NULL, "https://google.ca", "Google 3.htm", 0, NULL);
    // MyDownloadFunction(NULL, "https://google.ca", "Google 4.htm", 0, NULL);
    // MyDownloadFunction(NULL, "https://google.ca", "Google 5.htm", 0, NULL);

    for (int i = 1; i <= 5; i++) {
        URL << "https://MyWebsite.com/" << i << "/";
        cout << URL.str() << "\r\n";

        Iteration << i << ".htm";
        cout << Iteration.str() << "\r\n\r\n";

        MyDownloadFunction(NULL, URL.str().c_str(), Iteration.str().c_str(), 0, NULL);

        URL.str("");
        Iteration.str("");
    }
}

1 个答案:

答案 0 :(得分:1)

URLDownloadToFile(以及大多数其他Windows API函数)使用stdcall调用约定而不是ccall约定。此外,第一个和最后一个参数不是void*,它们是LPUNKNOWNLPBINDSTATUSCALLBACK,它返回HRESULT,而不是int*。通过指向不同类型的指针调用一种类型的函数是未定义的行为。因此,您需要将typedef更改为:

typedef HRESULT (__stdcall *MyDownloadToUrl)(LPUNKNOWN, const char*, const char*, DWORD, LPBINDSTATUSCALLBACK);