2015-03-19 69 views
0

我有一些wav聲音,我想從線程播放。當程序啓動時,我將聲音加載到內存中,然後使用Windows功能PlaySound播放它們。這有效,但是當我嘗試播放線程中的聲音時,出現AccessViolationException,「嘗試讀取或寫入受保護的內存」。從導致AccessViolationException的線程訪問文件緩衝區

有沒有辦法將文件加載到char數組中,然後從單獨的線程讀取它?

這是我用來加載聲音文件並播放它的代碼。

// Code to load sound from file into char*. 
 
    ifstream ifs(WaveSounds::sounds::StartupMusic, ios::binary | ios::ate); 
 
\t // The ios::ate flag sets the filestream 
 
\t // to the end position, so it's already 
 
\t // ata the end when we call 'tellg()'. 
 
\t if (&std::ios::ios_base::good) 
 
\t { \t \t 
 
\t \t int length = ifs.tellg(); 
 
\t \t ifs.seekg(0, ifs.beg); 
 
\t \t // Load into the Char * , 'n_StartMusic'. 
 
\t \t n_StartMusic = new char[length]; 
 
\t \t ifs.read(n_StartMusic, length); 
 
\t \t ifs.close(); 
 
\t } 
 

 
// Plays sound from thread, causes AccessViolationException. 
 
static void PlaySoundThread() 
 
{ \t \t 
 
\t PlaySound((LPWSTR)WaveSounds::n_CurSound, NULL, SND_MEMORY | SND_ASYNC); 
 
} 
 

 
// Method that sets sound to play and starts thread. 
 
void WaveSounds::Play_Sound(char* sound) 
 
{ \t \t 
 
\t n_CurSound = sound; 
 
\t n_hmod = GetModuleHandle(0); 
 
\t Thread^ t = gcnew Thread(gcnew ThreadStart(PlaySoundThread)); 
 
\t t->IsBackground = true; 
 
\t t->Start(); \t 
 
}

回答

0

如果字符*聲音通過wave.play_sound(& C)傳遞到你的函數棧上;在線程啓動的時候c可能已經被刪除,所以m_nCurSound指向已清空的內存。

修復這個改變m_nCurSound = sound到m_nCurSound = new char [255]; strcpy(sound,m_nCurSound);

+0

是的,就是這樣。該文件被加載到類的初始化器中,但是我通過在我調用它的同一個函數中聲明類的實例來測試它,所以它將它加載到堆棧而不是堆中。當我宣佈一個單獨的類的實例,然後嘗試它時,它工作正常。菜鳥的錯誤,因爲我還是C++的新手。謝謝! – netcat 2015-03-19 05:20:00