程序有
GetLocalIP,IsWanLinked,UploadFile,ShowMessage四个静态函数。
作用分别为
GetLocalIP得到系统的IP。
IsWanLinked检测计算机是否接入WAN。
UpLoadFile 用WININET类给FTP服务器上传文件。
ShowMessage在系统托盘用气泡的方式显示消息。
它们的关系是:
UpLoadFile调用其它三个函数。问题:
当我用
AfxBeginThread((AFX_THREADPROC)UploadFile,(LPVOID)this,THREAD_PRIORITY_NORMAL,0,0,NULL);
启动UpLoadFile时,编译器在DEBUG状态下编译正常,当调用线程时会报错。
错误如下:
Debug Assertion Failed!
Prgram:....mypro.exe
File:wincore.cpp
Line:888
For infomation on how your program can cause an assertion failure,
see the Visual c++ documentation on asserts.在Release状态下,能正常编译也可正常执行,不会出错。
各位兄弟,有没有遇到过这样的情况,帮帮忙呀,快急死了。
我用的是,VISUAL C++.NET 2003,WINXP SP2

解决方案 »

  1.   

    严重警告,你的程序存在严重隐患,虽然在发布版本中暂时没有表露出来.你跟踪一下,可以看到,你所调用的一些系统函数里,有"assert()"语句,是用来检查一些变量范围是否符合函数要求. 而在正式版本中就没有该语句.
      比如: bool aaa();//调用成功则返回ture
            main()
             {
                bool bb=aaa();
                assert(bb);  //在调试版中,该语句能检查你的一些变量的值是否满足你的要求.
              }我在你的错误信息中看到了相关信息,你可以根据这个线索自己再看看
      

  2.   

    错误信息说明你在assert宏上面出错了;
    assert只有在debug下才起到提示警告变量非法的作用,在Release下则不起任何作用;
    正是因为这样,假如Debug下一些变量非法,编译器会抱错,而Release下不会报错,
    但是Release下不报错并不是好事情,因为你的程序在Debug下就有问题(变量非法),虽然release下不报错,
    但是程序存在着极大的安全隐患,可能导致你程序崩溃。
    所以不要放过你每一步Assert变量检查,看看该处变量是否非法....
      

  3.   

    找了好久也没找到错误在哪?我把出错程序贴出来,大家帮着看看,先谢谢大家了!!int CActiveHostDlg::GetLocalIP(char* buff)
    {
    CString hostname,ip;
    struct hostent *host;
    buff[0]='\0';
       
    gethostname(hostname.GetBuffer (255),255);
    hostname.ReleaseBuffer ();
    host=gethostbyname(hostname.GetBuffer ());

    for(int i=0;host->h_addr_list[i]!=NULL ;i++)
    {
      
    ip.Format("%s",inet_ntoa(*((in_addr*)host->h_addr_list [i])));
      if(strcmp(ip.Left (7),"192.168")!=0 &&  strcmp(ip.Left (2),"10")!=0)
      {
      strcpy(buff,ip.GetBuffer ());
     return 1;
      }
    }

    //MessageBox(hostname);


    return 0;
    }int CActiveHostDlg::IsWANLinked(void)
    {
    CInternetSession session;
    CHttpFile *file;
    try
    {
    file=(CHttpFile*)session.OpenURL("http://www.163.com"); if(file)
    {
    file->Close ();
    session.Close ();
    delete file;
    return 1;

    }
    else
    return 0;
    }
    catch (CInternetException *e)
    {
    e->Delete ();
    return 0;
    }


    return 0;
    }UINT CActiveHostDlg::UploadFile(LPVOID pWnd)
    {
    CInternetSession session;
    CFtpConnection *ftp=NULL;
    CStdioFile file;
    CActiveHostDlg *dlg=(CActiveHostDlg*)pWnd;
    dlg->m_basicdlg .UpdateData ();
    try
    {
    if(IsWANLinked())
    {
    ftp=session.GetFtpConnection (dlg->m_basicdlg.m_ftpserver,dlg->m_basicdlg.m_user,dlg->m_basicdlg.m_password,dlg->m_basicdlg.m_ftpport);
    if(ftp)
    {
    DeleteFile("c:\\index.htm");
    file.Open ("c:\\index.htm",CFile::modeCreate | CFile::modeWrite );
    if(file)
    {
    CString ip;
    char wanip[255];
    GetLocalIP(wanip);
    if(dlg->m_basicdlg.islocal )
    ip.Format ("<meta http-equiv=\"refresh\" content=\"5;url=http://%s:%d\">",wanip,dlg->m_basicdlg.m_serverport );
    else
    ip.Format ("<meta http-equiv=\"refresh\" content=\"5;url=http://%s\">",dlg->m_basicdlg.m_webserver );
    file.WriteString ("<html>\r\n<head>\r\n");
    file.WriteString (ip);
    file.WriteString ("\r\n</head>\r\n<font name=\"黑体\" size=3>页面跳转中......</font>\r\n</html>");
    file.Close ();

    CFtpFileFind findfile(ftp);
    if(findfile.FindFile (dlg->m_basicdlg.m_path))
    if(!ftp->Remove (dlg->m_basicdlg.m_path))
    AfxMessageBox("delete ftpfile error!",0,0);

    ftp->PutFile ("c:\\index.htm",dlg->m_basicdlg.m_path );
    //AfxMessageBox("upload ok",0,0);
    ShowMessage(dlg->m_hIcon,"服务器更新成功",dlg->m_hWnd ); }
    ftp->Close ();
    delete ftp;
    ftp=NULL;
    DeleteFile("c:\\index.htm");
    }
    session.Close ();
    }
    else
    ShowMessage(dlg->m_hIcon,"网络没有联接,请检查网络。",dlg->m_hWnd);
    }
    catch(CInternetException *e)
    {
      char errmsg[255];
    e->GetErrorMessage (errmsg,255);
    CString msg;
    msg.Format ("服务器更新失败!\r\n%s",errmsg);
    ShowMessage(dlg->m_hIcon,msg.GetBuffer (),dlg->m_hWnd );
      if(ftp)
      {
    ftp->Close ();
    delete ftp;
      }
      e->Delete ();
    }

    return 0;
    }void CActiveHostDlg::ShowMessage(HICON hicon, char* msg,HWND hwnd)
    {
    NOTIFYICONDATA icondata;
    icondata.cbSize =sizeof(NOTIFYICONDATA);
    icondata.hWnd =hwnd ;
    icondata.hIcon =hicon;
    icondata.uID =IDR_MAINFRAME;
    strcpy(icondata.szTip,"ActiveHost");
    icondata.uCallbackMessage =WM_ICONMESSAGE;
    icondata.uFlags =NIF_ICON | NIF_INFO | NIF_MESSAGE | NIF_TIP; icondata.dwInfoFlags=NIIF_INFO;
    strcpy(icondata.szInfo,msg);
    strcpy(icondata.szInfoTitle,"ActiveHost");
    icondata.uTimeout =5;
    icondata.uVersion =0x03;
    Shell_NotifyIcon(NIM_MODIFY,&icondata);}void CActiveHostDlg::OnShellupUpdate()
    {
    // TODO: 在此添加命令处理程序代码

    AfxBeginThread((AFX_THREADPROC)UploadFile,(LPVOID)this,THREAD_PRIORITY_NORMAL,0,0,NULL);
    //DWORD id;
    //CreateThread(0,0,(LPTHREAD_START_ROUTINE)UploadFile,(LPVOID)this,0,&id);
    }
      

  4.   

    应该是非法窗体指针的问题,建议你在OnShellupUpdate 里面先做掉关于CActiveHostDlg 的所有操作(比如UpdateData 之类的)然后把传输文件需要的参数定义一个结构体,new 这个结构体的变量,填充相关属性后,传到线程里,在线程函数的最后delete 这个变量
      

  5.   

    UINT CActiveHostDlg::UploadFile(LPVOID pWnd)
    {
    CInternetSession session;
    CFtpConnection *ftp=NULL;
    CStdioFile file;
    CActiveHostDlg *dlg=(CActiveHostDlg*)pWnd;
    dlg->m_basicdlg .UpdateData (); //dlg指针属于界面线程,你在工作线程中调用了界面相关的代码,msdn中建议不要在线程之间传递mfc对象指针,如果你一定要调用,可以采取发送自定义消息的方法,改为调用 dlg->m_basicdlg.SendMessage(WM_USERDEFINE),在该消息处理函数中调用UpdateData()
      

  6.   

    ASSERT((p = pMap->LookupPermanent(m_hWnd)) != NULL ||
    (p = pMap->LookupTemporary(m_hWnd)) != NULL);跨线程传递CWnd*就会存在这个问题因为CWnd*与HWND之间的映射是通过一个线程局部存储的MAP来做的。
      

  7.   

    // Note: if either of the above asserts fire and you are
    // writing a multithreaded application, it is likely that
    // you have passed a C++ object from one thread to another
    // and have used that object in a way that was not intended.
    // (only simple inline wrapper functions should be used)
    //
    // In general, CWnd objects should be passed by HWND from
    // one thread to another.  The receiving thread can wrap
    // the HWND with a CWnd object by using CWnd::FromHandle.
    //
    // It is dangerous to pass C++ objects from one thread to
    // another, unless the objects are designed to be used in
    // such a manner.上面这几行是MFC源代码中有关的注释,看了过后是不是明白了?应该传递HWND,然后在目标线程使用CWnd::FromHandle