none
HRESULT函数导出问题 RRS feed

  • 问题

  • 最近碰到这么个问题,在改造以前的一个用VC6.0 下写的DLL是,凡是返回为HRESULT类型的函数均无法导出,在同一个DLL中我又对原来的HRESULT返回函数进行了封装,函数可以导出,但是在函数运行结束后又出现了User breakpoint called from code at ...的提示,当我把调用HRESULT返回类型的函数注释掉后,函数以上现象就消失掉了,请问有没有哪位大侠碰到过,是如何将HRESULT返回类型的函数成功导出。在线等待。

    2008年11月24日 2:47

答案

  •  

    谢谢各位的热心,问题已经弄清了,实际和函数的返回类型没有多大的关系,初步判定应该是内存泄露导致,因为上次测试的时候添加的LIB没有把原来的删除掉,新添加的以HRESULT函数将原来的Lib和DLL函数删除后,可以导出,没有什么问题,代码如下,目前我只知道代码存在问题,还没有查清,代码如下:

    HRESULT CVaultFileStub::get_file(const PTSTR vault_name,const PTSTR dir_path,const PTSTR file_name,const PTSTR destfilename,BOOL bEncrypt)
    {

     /*
        if (GetParam2(2049)==_T("Encrypt=TRUE"))
     {
      if (bEncrypt)
      bEncrypt=TRUE;
      else bEncrypt=FALSE;
     } else bEncrypt=FALSE;
     */
     bEncrypt=FALSE;
     /************************************************************************/
     /* 在本地创建相应的文件                                                 */
     /************************************************************************/
     DWORD dwErr ;
     DWORD dwCrcVal = 0;
     CString strFileCommandID(_T(""));
     BOOL bFileExist = FALSE;
     try
     {
      if(PathFileExists(destfilename))
      {
       bFileExist =  TRUE;
       DWORD dwAttrs = GetFileAttributes(destfilename);
       if ((dwAttrs & FILE_ATTRIBUTE_READONLY))
       {
        SetFileAttributes(destfilename,
         dwAttrs & ~FILE_ATTRIBUTE_READONLY);
       }
      }


      CString strFileExt(_T(""));
      strFileExt = file_name;
      int nPos = strFileExt.Find(_T('.'));
      strFileExt = strFileExt.Right(strFileExt.GetLength()-nPos-1);

      strFileCommandID = get_filecommand_id();
      //应该先获取文件大小,然后按文件大小建立文件。
      DWORD dwCrc = 0;
      ULONG actual_filesize = 0;
      //多线程获取并写入文件
      if(m_nThreadNum <= 0) m_nThreadNum = 1;
      ULONG nThreadNum = m_nThreadNum;
      ULONG ulBufSize = NET_DATA_BUFF_SIZE;

      HRESULT  hr = E_FAIL;
      int nRepeatCount = 0;
      DWORD dwTickCount = 0 ;
      begin_operator(nRepeatCount,dwTickCount);
      {
       CVaultFileStub stub;
       while(retry_operator(nRepeatCount,dwTickCount))
       {
        hr = stub.begin_get_buffer((PTSTR)(LPCTSTR)strFileCommandID,vault_name,dir_path,file_name,ulBufSize,
         (PTSTR)(LPCTSTR)strFileExt,actual_filesize,&dwCrc,nThreadNum,bEncrypt,(bFileExist&&!bEncrypt));
        if (!FAILED(hr)) break;
        if ((hr == E_HRESULT_NETFILE_SEND_ERROR)||(hr == E_HRESULT_NETFILE_READ_ERROR)||(hr == E_HRESULT_NETFILE_NOT_CONNECT))
        {
         stub.release();
        }
       }
       if(FAILED(hr))
       {
        return hr;
       }
       
       if(!bEncrypt&&bFileExist)//在不加密的情况下,才要进行crc校验
       {
        
        CCrc32Static static_crc;
        DWORD dwCrcVal = 0;
        if (static_crc.FileCrc32Win32(destfilename,dwCrcVal) != ERROR_CRC)
        {
         if( dwCrcVal == dwCrc) 
         {
          hr = stub.end_get_buffer((PTSTR)(LPCTSTR)strFileCommandID,FALSE);
          if(FAILED(hr))
          {
           //return hr;
          }  
          return S_OK;
         }
        }
        
       }
      }
      //如果加密,则获取临时文件名
      if (!m_file.Open(destfilename,CFile::modeCreate|CFile::modeWrite|CFile:Tongue TiedhareDenyNone))
      {
       return E_HRESULT_ERROR_WRITEFILE;
      }
      
      m_file.SetLength(actual_filesize);
      m_file.Seek(0,CFile::begin);

      CMutex mutex;
      ULONG nTransmitCount = 0;
      ULONG nThreadTransmitNum = 0;
      nTransmitCount = actual_filesize/ulBufSize;
      if (nTransmitCount == 0 )
      {
       nTransmitCount = 1;
      }
      if (nTransmitCount*ulBufSize < actual_filesize)
      { 
       nTransmitCount++;
      }
      ULONG nFuncTransmitCount = 0;
      BOOL  bExitThread = FALSE;

      m_threads = new CWinThread*[nThreadNum];
      for (UINT i = 0; i < nThreadNum; i++)
      { 
       FileThreadInfo *info = new FileThreadInfo;
       memset(info,0,sizeof(FileThreadInfo));
       info->pFile = &m_file;
       info->nIndex = i;
       //info->nThreadNum = nThreadNum;
       //_tcsncpy(info->vaultname,vault_name,40);
       //_tcsncpy(info->dirpath,dir_path,255);
       //_tcsncpy(info->filename,file_name,127);
       //_tcsncpy(info->chFileName,(LPCTSTR)destfilename,255);

       info->bufsize = ulBufSize;
       info->filesize = actual_filesize;
       info->bEncrypt = bEncrypt;
       info->pMutex = &mutex;
       info->filecommandid = (PTSTR)(LPCTSTR)strFileCommandID;
       info->nTransmitCount = nTransmitCount;
       info->pTransmitNum = &nFuncTransmitCount;
       info->pExit = &bExitThread;

       m_threadsIdea = AfxBeginThread(DownloadThread, (PVOID)info,
        THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED, NULL);
       if(m_threadsIdea == NULL)
       {
        delete info;
        delete []m_threads;
        return E_HRESULT_UNKNOWN_ERROR;
       }
       m_threadsIdea->m_pMainWnd = CWnd::FromHandle(_ghwndMainFrm);
       m_threadsIdea->m_bAutoDelete = FALSE;
       m_threadsIdea->ResumeThread();
      }
      
      //等待线程的执行,获取线程执行结果
      HANDLE *hThreads = new HANDLE[nThreadNum];
      for ( i = 0; i < nThreadNum; i++)
      {
       hThreadsIdea = m_threadsIdea->m_hThread;
      }
      DWORD dw = WaitForMultipleObjects(nThreadNum, hThreads, TRUE, INFINITE);
      delete[]hThreads;
      //if ((dw >= WAIT_OBJECT_0)&& (dw <= WAIT_OBJECT_0 + nThreadNum - 1))
      if (dw != 0xFFFFFFFF)
      { 
       HRESULT hr = S_OK;
       for (UINT i = 0; i < nThreadNum; i++)
       {
        DWORD code;
        BOOL bRet = GetExitCodeThread(m_threadsIdea->m_hThread,&code);
        if(bRet && FAILED(code))
         hr = code;
        delete m_threadsIdea;
       }
       delete [] m_threads;
       m_threads = NULL;
       //关闭文件
       m_file.Close();
       CVaultFileStub stub;
       if (FAILED(hr))
       {
        if (!FAILED(stub.CreateConnection()))
        {
         stub.end_get_buffer((PTSTR)(LPCTSTR)strFileCommandID,FALSE);
        }
       }
       else
       {
        int nRepeatCount = 0;
        DWORD dwTickCount = 0 ;
        HRESULT hrConnect = S_OK;
        begin_operator(nRepeatCount,dwTickCount);
        hrConnect = stub.CreateConnection();
        while(retry_operator(nRepeatCount,dwTickCount))
        {
         if (!FAILED(hrConnect))
         {
          hr = stub.end_get_buffer((PTSTR)(LPCTSTR)strFileCommandID,TRUE);
          if (!FAILED(hr)) break;
          if (FAILED(hr))
          {
           if ((hr == E_HRESULT_NETFILE_SEND_ERROR)||(hr == E_HRESULT_NETFILE_READ_ERROR))
           {
            stub.release();
            hrConnect = stub.CreateConnection();
           }
          }
         }
         else
         {
          stub.release();
          hrConnect = stub.CreateConnection();
          continue;
         }
        }
       }
       return hr;
      }
      else
      {
       for (UINT i = 0; i < nThreadNum; i++)
        delete m_threadsIdea;
       delete [] m_threads;
       m_threads = NULL;
       //关闭文件
       m_file.Close();
       CVaultFileStub stub;
       if (!FAILED(stub.CreateConnection()))
       {
        stub.end_get_buffer((PTSTR)(LPCTSTR)strFileCommandID,FALSE);
       }
       dwErr = E_HRESULT_NETFILE_SERVICE_SHUTDOWN;
       return dwErr;
      }
     }
     catch(CFileException* )
     {
      if (!strFileCommandID.IsEmpty())
      {
       CVaultFileStub stub;
       if (!FAILED(stub.CreateConnection()))
       {
        stub.end_get_buffer((PTSTR)(LPCTSTR)strFileCommandID,FALSE);
       }
      }
      dwErr = E_HRESULT_ERROR_WRITEFILE;
      return dwErr;
     }
     catch(...)
     {
      if (!strFileCommandID.IsEmpty())
      {
       CVaultFileStub stub;
       if (!FAILED(stub.CreateConnection()))
       {
        stub.end_get_buffer((PTSTR)(LPCTSTR)strFileCommandID,FALSE);
       }
      }
      dwErr = E_HRESULT_UNKNOWN_ERROR;
      return dwErr;
     }
    }

    感兴趣的朋友,可以看看。只是不清楚具体问题出在那个地方。
    2008年11月25日 6:04

全部回复

  • 能贴点代码出来么?

    2008年11月24日 14:36
    版主
  • 一些特定的回调函数有时候会要求特定的返回类型,我之前碰到一个类似的,你看看是不是这方面的问题

    2008年11月25日 5:02
  •  

    谢谢各位的热心,问题已经弄清了,实际和函数的返回类型没有多大的关系,初步判定应该是内存泄露导致,因为上次测试的时候添加的LIB没有把原来的删除掉,新添加的以HRESULT函数将原来的Lib和DLL函数删除后,可以导出,没有什么问题,代码如下,目前我只知道代码存在问题,还没有查清,代码如下:

    HRESULT CVaultFileStub::get_file(const PTSTR vault_name,const PTSTR dir_path,const PTSTR file_name,const PTSTR destfilename,BOOL bEncrypt)
    {

     /*
        if (GetParam2(2049)==_T("Encrypt=TRUE"))
     {
      if (bEncrypt)
      bEncrypt=TRUE;
      else bEncrypt=FALSE;
     } else bEncrypt=FALSE;
     */
     bEncrypt=FALSE;
     /************************************************************************/
     /* 在本地创建相应的文件                                                 */
     /************************************************************************/
     DWORD dwErr ;
     DWORD dwCrcVal = 0;
     CString strFileCommandID(_T(""));
     BOOL bFileExist = FALSE;
     try
     {
      if(PathFileExists(destfilename))
      {
       bFileExist =  TRUE;
       DWORD dwAttrs = GetFileAttributes(destfilename);
       if ((dwAttrs & FILE_ATTRIBUTE_READONLY))
       {
        SetFileAttributes(destfilename,
         dwAttrs & ~FILE_ATTRIBUTE_READONLY);
       }
      }


      CString strFileExt(_T(""));
      strFileExt = file_name;
      int nPos = strFileExt.Find(_T('.'));
      strFileExt = strFileExt.Right(strFileExt.GetLength()-nPos-1);

      strFileCommandID = get_filecommand_id();
      //应该先获取文件大小,然后按文件大小建立文件。
      DWORD dwCrc = 0;
      ULONG actual_filesize = 0;
      //多线程获取并写入文件
      if(m_nThreadNum <= 0) m_nThreadNum = 1;
      ULONG nThreadNum = m_nThreadNum;
      ULONG ulBufSize = NET_DATA_BUFF_SIZE;

      HRESULT  hr = E_FAIL;
      int nRepeatCount = 0;
      DWORD dwTickCount = 0 ;
      begin_operator(nRepeatCount,dwTickCount);
      {
       CVaultFileStub stub;
       while(retry_operator(nRepeatCount,dwTickCount))
       {
        hr = stub.begin_get_buffer((PTSTR)(LPCTSTR)strFileCommandID,vault_name,dir_path,file_name,ulBufSize,
         (PTSTR)(LPCTSTR)strFileExt,actual_filesize,&dwCrc,nThreadNum,bEncrypt,(bFileExist&&!bEncrypt));
        if (!FAILED(hr)) break;
        if ((hr == E_HRESULT_NETFILE_SEND_ERROR)||(hr == E_HRESULT_NETFILE_READ_ERROR)||(hr == E_HRESULT_NETFILE_NOT_CONNECT))
        {
         stub.release();
        }
       }
       if(FAILED(hr))
       {
        return hr;
       }
       
       if(!bEncrypt&&bFileExist)//在不加密的情况下,才要进行crc校验
       {
        
        CCrc32Static static_crc;
        DWORD dwCrcVal = 0;
        if (static_crc.FileCrc32Win32(destfilename,dwCrcVal) != ERROR_CRC)
        {
         if( dwCrcVal == dwCrc) 
         {
          hr = stub.end_get_buffer((PTSTR)(LPCTSTR)strFileCommandID,FALSE);
          if(FAILED(hr))
          {
           //return hr;
          }  
          return S_OK;
         }
        }
        
       }
      }
      //如果加密,则获取临时文件名
      if (!m_file.Open(destfilename,CFile::modeCreate|CFile::modeWrite|CFile:Tongue TiedhareDenyNone))
      {
       return E_HRESULT_ERROR_WRITEFILE;
      }
      
      m_file.SetLength(actual_filesize);
      m_file.Seek(0,CFile::begin);

      CMutex mutex;
      ULONG nTransmitCount = 0;
      ULONG nThreadTransmitNum = 0;
      nTransmitCount = actual_filesize/ulBufSize;
      if (nTransmitCount == 0 )
      {
       nTransmitCount = 1;
      }
      if (nTransmitCount*ulBufSize < actual_filesize)
      { 
       nTransmitCount++;
      }
      ULONG nFuncTransmitCount = 0;
      BOOL  bExitThread = FALSE;

      m_threads = new CWinThread*[nThreadNum];
      for (UINT i = 0; i < nThreadNum; i++)
      { 
       FileThreadInfo *info = new FileThreadInfo;
       memset(info,0,sizeof(FileThreadInfo));
       info->pFile = &m_file;
       info->nIndex = i;
       //info->nThreadNum = nThreadNum;
       //_tcsncpy(info->vaultname,vault_name,40);
       //_tcsncpy(info->dirpath,dir_path,255);
       //_tcsncpy(info->filename,file_name,127);
       //_tcsncpy(info->chFileName,(LPCTSTR)destfilename,255);

       info->bufsize = ulBufSize;
       info->filesize = actual_filesize;
       info->bEncrypt = bEncrypt;
       info->pMutex = &mutex;
       info->filecommandid = (PTSTR)(LPCTSTR)strFileCommandID;
       info->nTransmitCount = nTransmitCount;
       info->pTransmitNum = &nFuncTransmitCount;
       info->pExit = &bExitThread;

       m_threadsIdea = AfxBeginThread(DownloadThread, (PVOID)info,
        THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED, NULL);
       if(m_threadsIdea == NULL)
       {
        delete info;
        delete []m_threads;
        return E_HRESULT_UNKNOWN_ERROR;
       }
       m_threadsIdea->m_pMainWnd = CWnd::FromHandle(_ghwndMainFrm);
       m_threadsIdea->m_bAutoDelete = FALSE;
       m_threadsIdea->ResumeThread();
      }
      
      //等待线程的执行,获取线程执行结果
      HANDLE *hThreads = new HANDLE[nThreadNum];
      for ( i = 0; i < nThreadNum; i++)
      {
       hThreadsIdea = m_threadsIdea->m_hThread;
      }
      DWORD dw = WaitForMultipleObjects(nThreadNum, hThreads, TRUE, INFINITE);
      delete[]hThreads;
      //if ((dw >= WAIT_OBJECT_0)&& (dw <= WAIT_OBJECT_0 + nThreadNum - 1))
      if (dw != 0xFFFFFFFF)
      { 
       HRESULT hr = S_OK;
       for (UINT i = 0; i < nThreadNum; i++)
       {
        DWORD code;
        BOOL bRet = GetExitCodeThread(m_threadsIdea->m_hThread,&code);
        if(bRet && FAILED(code))
         hr = code;
        delete m_threadsIdea;
       }
       delete [] m_threads;
       m_threads = NULL;
       //关闭文件
       m_file.Close();
       CVaultFileStub stub;
       if (FAILED(hr))
       {
        if (!FAILED(stub.CreateConnection()))
        {
         stub.end_get_buffer((PTSTR)(LPCTSTR)strFileCommandID,FALSE);
        }
       }
       else
       {
        int nRepeatCount = 0;
        DWORD dwTickCount = 0 ;
        HRESULT hrConnect = S_OK;
        begin_operator(nRepeatCount,dwTickCount);
        hrConnect = stub.CreateConnection();
        while(retry_operator(nRepeatCount,dwTickCount))
        {
         if (!FAILED(hrConnect))
         {
          hr = stub.end_get_buffer((PTSTR)(LPCTSTR)strFileCommandID,TRUE);
          if (!FAILED(hr)) break;
          if (FAILED(hr))
          {
           if ((hr == E_HRESULT_NETFILE_SEND_ERROR)||(hr == E_HRESULT_NETFILE_READ_ERROR))
           {
            stub.release();
            hrConnect = stub.CreateConnection();
           }
          }
         }
         else
         {
          stub.release();
          hrConnect = stub.CreateConnection();
          continue;
         }
        }
       }
       return hr;
      }
      else
      {
       for (UINT i = 0; i < nThreadNum; i++)
        delete m_threadsIdea;
       delete [] m_threads;
       m_threads = NULL;
       //关闭文件
       m_file.Close();
       CVaultFileStub stub;
       if (!FAILED(stub.CreateConnection()))
       {
        stub.end_get_buffer((PTSTR)(LPCTSTR)strFileCommandID,FALSE);
       }
       dwErr = E_HRESULT_NETFILE_SERVICE_SHUTDOWN;
       return dwErr;
      }
     }
     catch(CFileException* )
     {
      if (!strFileCommandID.IsEmpty())
      {
       CVaultFileStub stub;
       if (!FAILED(stub.CreateConnection()))
       {
        stub.end_get_buffer((PTSTR)(LPCTSTR)strFileCommandID,FALSE);
       }
      }
      dwErr = E_HRESULT_ERROR_WRITEFILE;
      return dwErr;
     }
     catch(...)
     {
      if (!strFileCommandID.IsEmpty())
      {
       CVaultFileStub stub;
       if (!FAILED(stub.CreateConnection()))
       {
        stub.end_get_buffer((PTSTR)(LPCTSTR)strFileCommandID,FALSE);
       }
      }
      dwErr = E_HRESULT_UNKNOWN_ERROR;
      return dwErr;
     }
    }

    感兴趣的朋友,可以看看。只是不清楚具体问题出在那个地方。
    2008年11月25日 6:04