相同的代码,在VC6.0和VS2010的不同结果?
利用Win32API要实现一个录音功能,在VC6好使,但VS2010下不能用。为了测试,创建了2个简单的基于dialog 的MFC程序,一个在VC6下,一个在VS2010下。相同的代码,但结果不一样,VC6得到的结果无论是debug或者release都正确,而VS2010下则2中版本都不正确。对比了VC6和VS2010的编译默认优化设置,VC6中release版本Inline function expansion->Only __Inline(/Ob1),而VS2010中release版本Inline function expansion->Default,如今将VS2010的这个参数设置Inline function expansion->Only __Inline(/Ob1),则release版本可以得出正确的结果。
这个bug跟踪2个星期了,现在还没有任何头绪,各位帮忙分析一下原因,谢谢!
再次声明,VC6和VS2010下面的代码是一样的
// MyPlayerDlg.h : header file#pragma once#include "../globle.h"#include <mmsystem.h>// CMyPlayerDlg dialogclass CMyPlayerDlg : public CDialogEx{// Constructionpublic: CMyPlayerDlg(CWnd* pParent = NULL); // standard constructorpublic: void InitializeVariable(); //集中初始化一些变量 bool OpenWriteFiles(); void StartAudioRecord(); // static void *WriteAudioFile(tPara *Param); void SaveAudioFile(); //wave in callback function static bool PASCAL waveInCallback(HWAVEIN hin, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2); //the ture function to process callback bool waveInProc(HWAVEIN hin, UINT uMsg, DWORD dwParam1, DWORD dwParam2); void Init_Coder_G723();public: //audio member variable volatile HWAVEIN m_hWaveIn; //wave in handle volatile PWAVEHDR m_pWavHdr[BUFFER_NUM]; //audio header volatile int m_nIndex; volatile int m_iSize; HANDLE m_hEventCode; //编码线程同步事件 BOOL m_exit_write_thread; //退出编码线程标志 CWinThread* m_ThreadCoder; //编码线程指针 static UINT ThreadCoder(LPVOID lParam); //处理音频编码线程 unsigned int CoderThreadProc(); //coder Thread function CRITICAL_SECTION m_csCod; //编码线程临界区// Dialog Data enum { IDD = IDD_MYPLAYER_DIALOG }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support// Implementationprotected: HICON m_hIcon; // Generated message map functions virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP()public: afx_msg void OnBnClickedOk(); afx_msg void OnBnClickedCancel();};// MyPlayerDlg.cpp : implementation file//#include "stdafx.h"#include "MyPlayer.h"#include "MyPlayerDlg.h"#include "afxdialogex.h"#ifdef _DEBUG#define new DEBUG_NEW#endif#include "../audio.h"#pragma comment(lib, "vfw32")#pragma comment(lib, "winmm")#include <deque>std::deque <PWAVEHDR> g_pWaveDeque(BUFFER_NUM, NULL);std::deque <PWAVEHDR>::iterator deqpos;FILE* fw723;FILE* fLog;int g_iCount_buff; //just for testint g_iCount_add; //just for test//省略一些编译器生成的编码BOOL CMyPlayerDlg::OnInitDialog(){ CDialogEx::OnInitDialog(); //删除一些编译器生成的编码 // TODO: Add extra initialization here if (fopen_s(&fLog, "../run.log", "wb") != 0) { return FALSE; } InitializeVariable(); return TRUE; // return TRUE unless you set the focus to a control}void CMyPlayerDlg::OnSysCommand(UINT nID, LPARAM lParam){ if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialogEx::OnSysCommand(nID, lParam); }}// If you add a minimize button to your dialog, you will need the code below// to draw the icon. For MFC applications using the document/view model,// this is automatically done for you by the framework.void CMyPlayerDlg::InitializeVariable(){ fw723 = NULL; //audio variable initialize m_nIndex = 0; m_hWaveIn = NULL; m_ThreadCoder = NULL; m_exit_write_thread = true; InitializeCriticalSection(&m_csCod); m_hEventCode = CreateEvent(NULL, FALSE, FALSE, NULL); memset((void*)m_pWavHdr, 0, BUFFER_NUM*sizeof(PWAVEHDR)); for (int i = 0; i < BUFFER_NUM; i++) { m_pWavHdr[i] = reinterpret_cast<PWAVEHDR>(malloc(sizeof(WAVEHDR))); g_pWaveDeque[i] = reinterpret_cast<PWAVEHDR>(malloc(sizeof(WAVEHDR))); g_pWaveDeque[i]->lpData = (LPSTR) new BYTE[INP_BUFFER_SIZE]; } g_pWaveDeque.clear();//清空所有元素 m_iSize = getAudioFramesize(); g_iCount_add = 0; g_iCount_buff = 0;}bool CMyPlayerDlg::OpenWriteFiles(){ const char AudioOut[] = "../UT11YY01.723"; if (fw723 == NULL) { if ( fopen_s(&fw723, AudioOut, "wb") != 0) { return false; } } return true;}void CMyPlayerDlg::StartAudioRecord(){ WAVEFORMATEX wftx; wftx = Init_audio_info(); //open the audio record device if success return 0 else return non 0 if (waveInOpen((LPHWAVEIN)&m_hWaveIn, WAVE_MAPPER, &wftx, (DWORD)waveInCallback, DWORD(this), CALLBACK_FUNCTION)) { return; } if (BUFFER_NUM%2 != 0) {//如果BUFFER_SIZE是基数则有(BUFFER_NUM/2)+1块内存添加到录音区 //如果是偶数则有BUFFER_NUM/2块被添加进去 m_nIndex = (BUFFER_NUM + 1)/2; } else { m_nIndex = BUFFER_NUM/2; } for (int i = 0; i < BUFFER_NUM; i++) { m_pWavHdr[i]->lpData = (LPSTR) new BYTE[INP_BUFFER_SIZE]; if (m_pWavHdr[i]->lpData == NULL) { } m_pWavHdr[i]->dwBufferLength = INP_BUFFER_SIZE; m_pWavHdr[i]->dwBytesRecorded = 0; m_pWavHdr[i]->dwUser = 0; m_pWavHdr[i]->dwFlags = 0; m_pWavHdr[i]->dwLoops = 1; m_pWavHdr[i]->lpNext = NULL; m_pWavHdr[i]->reserved = 0; waveInPrepareHeader(m_hWaveIn, m_pWavHdr[i], sizeof(WAVEHDR)); if (i < m_nIndex) { waveInAddBuffer(m_hWaveIn, m_pWavHdr[i], sizeof(WAVEHDR)); } }//end for if (m_exit_write_thread && m_ThreadCoder == NULL) { m_exit_write_thread = FALSE; m_ThreadCoder = AfxBeginThread(ThreadCoder, (LPVOID)this, THREAD_PRIORITY_NORMAL, 0, 0, NULL); Sleep(100); } //begin audio record waveInStart(m_hWaveIn);}bool PASCAL CMyPlayerDlg::waveInCallback(HWAVEIN hin, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2){ CMyPlayerDlg *pThis = (CMyPlayerDlg *)dwInstance; return pThis->waveInProc(hin, uMsg, dwParam1, dwParam2);}bool CMyPlayerDlg::waveInProc(HWAVEIN hin, UINT uMsg, DWORD dwParam1, DWORD dwParam2){ if (uMsg == WIM_DATA) {//receive data buffer EnterCriticalSection(&m_csCod); if (g_pWaveDeque.empty()) { g_pWaveDeque.push_front((PWAVEHDR)dwParam1); } else { deqpos = g_pWaveDeque.end(); //返回最后一个元素的下一个位置 if(g_pWaveDeque.size() < BUFFER_NUM) {//判断队列是否满 g_pWaveDeque.insert(deqpos, (PWAVEHDR)dwParam1); } } LeaveCriticalSection(&m_csCod); SetEvent(m_hEventCode); // 通知写文件 fprintf(fLog, "The process data numbers is %d\n", ++g_iCount_buff); } return true;}UINT CMyPlayerDlg::ThreadCoder(LPVOID lParam){ CMyPlayerDlg *pThis = (CMyPlayerDlg *)lParam; return pThis->CoderThreadProc();}UINT CMyPlayerDlg::CoderThreadProc(){ int nCount = 0; char Line[LINE_SIZE]; Word16 DataBuff[Frame]; memset(Line, 0, LINE_SIZE); memset(DataBuff, 0, Frame*sizeof(Word16)); PWAVEHDR pWaveHdr; while(!m_exit_write_thread) { WaitForSingleObject(m_hEventCode, INFINITE); EnterCriticalSection(&m_csCod); if (g_pWaveDeque.empty()) { continue; } pWaveHdr = g_pWaveDeque.front(); g_pWaveDeque.pop_front(); LeaveCriticalSection(&m_csCod); int nLen = pWaveHdr->dwBytesRecorded; int dwCount = (int)nLen/getAudioFramesize(); while(nCount < dwCount) { memcpy(DataBuff, pWaveHdr->lpData + nCount++*m_iSize, m_iSize); Coder(DataBuff, Line); Line_Wr(Line, fw723); } nCount = 0; waveInAddBuffer(m_hWaveIn, m_pWavHdr[m_nIndex++ % BUFFER_NUM], sizeof(WAVEHDR)); fprintf(fLog, "The add buffer numbers is %d\n", ++g_iCount_add); } return TRUE;}void CMyPlayerDlg::Init_Coder_G723(){ WrkRate = Rate63; //Rate63 WrkMode = Cod; //audio encode int i ; /* Initialize encoder data structure with zeros */ memset(&CodStat, 0, sizeof(CODSTATDEF)); /* Initialize the previously decoded LSP vector to the DC vector */ for ( i = 0 ; i < LpcOrder ; i ++ ) CodStat.PrevLsp[i] = LspDcTable[i] ; /* Initialize the taming procedure */ for(i=0; i<SizErr; i++) CodStat.Err[i] = Err0; return;}void CMyPlayerDlg::OnBnClickedOk(){ // TODO: Add your control notification handler code here OpenWriteFiles(); Sleep(100); Init_Coder_G723(); StartAudioRecord();// CDialogEx::OnOK();}void CMyPlayerDlg::OnBnClickedCancel(){ // TODO: Add your control notification handler code here waveInReset(m_hWaveIn); m_exit_write_thread = true; if (fw723 != NULL) { fclose(fw723); } if (fLog != NULL) { fclose(fLog); } // g_pWaveDeque.~deque<PWAVEHDR>(); CDialogEx::OnCancel();}