Anonymous
Вызовая метод воспроизведения объекта DirectSoundBuffer приводит к сбою под адреса
Сообщение
Anonymous » 14 июн 2025, 21:10
Я получаю сбой своего приложения при запуске моего кода под ASAN и выполняю метод воспроизведения объекта звукового буфера. < /p>
У меня есть несколько классов, связанных с созданием звука. Первый - это структура, которая содержит основные данные файла
wav .
Код: Выделить всё
struct WaveData
{
WAVEFORMATEX wfx;
BYTE* pData;
DWORD dwSize;
};
< /code>
Файл wav добавляется в решение Visual Studio в качестве ресурса.
Я принимаю идентификатор ресурса для создания звукового объекта-> < /p>
class sound
{
public:
sound(intptr_t resource_id);
bool is_valid() const noexcept;
bool play();
bool load_wave();
bool create_snd_buffer(const Microsoft::WRL::ComPtr& device);
private:
bool valid;
BYTE* locked_resource_;
HRSRC resource_handle_;
WaveData native_data_;
Microsoft::WRL::ComPtr sound_buffer_;
};
sound::sound(intptr_t resource_id) : valid{}, locked_resource_{}, native_data_{}
{
resource_handle_ = FindResource(GetModuleHandle(nullptr), MAKEINTRESOURCE(resource_id), xor ("WAVE").c_str());
if (resource_handle_ && (locked_resource_ = static_cast(LoadResource(GetModuleHandle(nullptr), resource_handle_))))
valid = true;
}
< /code>
звуки создают в классе звукового менеджера-> < /p>
class sound_manager
{
public:
sound_manager(HWND window);
~sound_manager();
bool play(sound_type type);
private:
std::map sounds;
std::random_device random_device;
std::mt19937 numbers;
Microsoft::WRL::ComPtr sound_device_;
};
sound_manager::sound_manager(HWND window)
{
if (DirectSoundCreate8(nullptr, &sound_device_, nullptr) == DS_OK)
sound_device_->SetCooperativeLevel(window, DSSCL_PRIORITY);
sounds =
{
{ access, { IDR_WAVE1, IDR_WAVE7, IDR_WAVE8, IDR_WAVE9 }},
{ me, { IDR_WAVE3, IDR_WAVE4, IDR_WAVE5 }},
{ shop, { IDR_WAVE2, IDR_WAVE6, IDR_WAVE11 }},
{ access_fail, { IDR_WAVE12 }},
{ access_click, { IDR_WAVE13 }},
{ inject_fail, { IDR_WAVE10 }},
};
}
< /code>
Мы выполняем этот код, когда вызовут метод воспроизведения Sound Manager-> < /p>
bool sound_manager::play(sound_type type)
{
auto& sound = sounds[type];
std::uniform_int_distribution engine(0, static_cast(sound.size() - 1));
auto& snd = sound[engine(numbers)];
if (!snd.is_valid() && (!snd.load_wave() || !snd.create_snd_buffer(sound_device_)))
return false;
return snd.play();
}
< /code>
is_valid, load_wave, create_snd_buffer-> < /p>
bool sound::is_valid() const noexcept
{
return valid && static_cast(sound_buffer_) && static_cast(native_data_.dwSize);
}
bool sound::load_wave()
{
DWORD resSize = SizeofResource(nullptr, resource_handle_);
if (!locked_resource_ || resSize < sizeof(RIFFLIST))
return false;
RIFFLIST* pRiff = reinterpret_cast(locked_resource_);
if (pRiff->chunk.fcc != FOURCC_RIFF || pRiff->fccListType != mmioFOURCC('W', 'A', 'V', 'E'))
return false;
BYTE* pWaveEnd = locked_resource_ + resSize;
BYTE* pChunk = locked_resource_ + sizeof(RIFFLIST);
WAVEFORMATEX* pFormat = nullptr;
BYTE* pWaveStart = nullptr;
DWORD waveSize = 0;
while (pChunk < pWaveEnd)
{
if (pChunk + sizeof(RIFFCHUNK) > pWaveEnd)
return false;
RIFFCHUNK* pCurrent = reinterpret_cast(pChunk);
DWORD chunkSize = pCurrent->cb;
if (pCurrent->fcc == mmioFOURCC('f', 'm', 't', ' ')) {
pFormat = reinterpret_cast(pChunk + sizeof(RIFFCHUNK));
if (pCurrent->cb > sizeof(WAVEFORMATEX)) return false;
memcpy(&native_data_.wfx, pFormat, sizeof(WAVEFORMATEX));
}
else if (pCurrent->fcc == mmioFOURCC('d', 'a', 't', 'a')) {
pWaveStart = pChunk + sizeof(RIFFCHUNK);
waveSize = pCurrent->cb;
}
DWORD padding = (chunkSize % 2) ? 1 : 0;
pChunk += sizeof(RIFFCHUNK) + chunkSize + padding;
if (pChunk > pWaveEnd)
return false;
}
if (!pFormat || !pWaveStart || !waveSize)
return false;
native_data_.pData = pWaveStart;
native_data_.dwSize = waveSize;
return true;
}
bool sound::create_snd_buffer(const Microsoft::WRL::ComPtr& device)
{
DSBUFFERDESC dsbd = {};
dsbd.dwSize = sizeof(DSBUFFERDESC);
dsbd.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS;
dsbd.dwBufferBytes = native_data_.dwSize;
dsbd.lpwfxFormat = &native_data_.wfx;
if (FAILED(device->CreateSoundBuffer(&dsbd, &sound_buffer_, nullptr)))
return false;
LPVOID pLocked = nullptr;
DWORD dwLockedSize = 0;
if (SUCCEEDED(sound_buffer_->Lock(0, 0, &pLocked, &dwLockedSize, nullptr, nullptr, DSBLOCK_ENTIREBUFFER)))
{
memcpy(pLocked, native_data_.pData, native_data_.dwSize);
sound_buffer_->Unlock(pLocked, dwLockedSize, nullptr, 0);
}
return true;
}
< /code>
Итак, после выполнения этих методов для инициализации звука я выполняю метод воспроизведения звукового объекта и звукового буфера.bool sound::play()
{
if (!sound_buffer_)
return false;
sound_buffer_->SetCurrentPosition(0);
sound_buffer_->SetVolume(DSBVOLUME_MAX);
return sound_buffer_->Play(0, 0, 0) == DS_OK;
}
Я получил сбой при достижении этой строки -> return sound_buffer _-> play (0, 0, 0) == ds_ok;
и эта проблема появляется только в том случае, если я запускаю проект под адресом.
Код: Выделить всё
00007FFF81D14CCC je CCommandManager::ParseRegistrationQueue+98h (07FFF81D14D3Ch)
00007FFF81D14CCE mov rdi,qword ptr [rsp+30h]
00007FFF81D14CD3 cmp dword ptr [rdi],0
rdi равен 0, но я не могу понять, как это возможно, если объекты инициализируются правильно, указатели верны и все выглядит хорошо.
Подробнее здесь:
https://stackoverflow.com/questions/795 ... ress-sanit
1749924650
Anonymous
Я получаю сбой своего приложения при запуске моего кода под ASAN и выполняю метод воспроизведения объекта звукового буфера. < /p> У меня есть несколько классов, связанных с созданием звука. Первый - это структура, которая содержит основные данные файла [b] wav [/b]. [code]struct WaveData { WAVEFORMATEX wfx; BYTE* pData; DWORD dwSize; }; < /code> Файл wav добавляется в решение Visual Studio в качестве ресурса. Я принимаю идентификатор ресурса для создания звукового объекта-> < /p> class sound { public: sound(intptr_t resource_id); bool is_valid() const noexcept; bool play(); bool load_wave(); bool create_snd_buffer(const Microsoft::WRL::ComPtr& device); private: bool valid; BYTE* locked_resource_; HRSRC resource_handle_; WaveData native_data_; Microsoft::WRL::ComPtr sound_buffer_; }; sound::sound(intptr_t resource_id) : valid{}, locked_resource_{}, native_data_{} { resource_handle_ = FindResource(GetModuleHandle(nullptr), MAKEINTRESOURCE(resource_id), xor ("WAVE").c_str()); if (resource_handle_ && (locked_resource_ = static_cast(LoadResource(GetModuleHandle(nullptr), resource_handle_)))) valid = true; } < /code> звуки создают в классе звукового менеджера-> < /p> class sound_manager { public: sound_manager(HWND window); ~sound_manager(); bool play(sound_type type); private: std::map sounds; std::random_device random_device; std::mt19937 numbers; Microsoft::WRL::ComPtr sound_device_; }; sound_manager::sound_manager(HWND window) { if (DirectSoundCreate8(nullptr, &sound_device_, nullptr) == DS_OK) sound_device_->SetCooperativeLevel(window, DSSCL_PRIORITY); sounds = { { access, { IDR_WAVE1, IDR_WAVE7, IDR_WAVE8, IDR_WAVE9 }}, { me, { IDR_WAVE3, IDR_WAVE4, IDR_WAVE5 }}, { shop, { IDR_WAVE2, IDR_WAVE6, IDR_WAVE11 }}, { access_fail, { IDR_WAVE12 }}, { access_click, { IDR_WAVE13 }}, { inject_fail, { IDR_WAVE10 }}, }; } < /code> Мы выполняем этот код, когда вызовут метод воспроизведения Sound Manager-> < /p> bool sound_manager::play(sound_type type) { auto& sound = sounds[type]; std::uniform_int_distribution engine(0, static_cast(sound.size() - 1)); auto& snd = sound[engine(numbers)]; if (!snd.is_valid() && (!snd.load_wave() || !snd.create_snd_buffer(sound_device_))) return false; return snd.play(); } < /code> is_valid, load_wave, create_snd_buffer-> < /p> bool sound::is_valid() const noexcept { return valid && static_cast(sound_buffer_) && static_cast(native_data_.dwSize); } bool sound::load_wave() { DWORD resSize = SizeofResource(nullptr, resource_handle_); if (!locked_resource_ || resSize < sizeof(RIFFLIST)) return false; RIFFLIST* pRiff = reinterpret_cast(locked_resource_); if (pRiff->chunk.fcc != FOURCC_RIFF || pRiff->fccListType != mmioFOURCC('W', 'A', 'V', 'E')) return false; BYTE* pWaveEnd = locked_resource_ + resSize; BYTE* pChunk = locked_resource_ + sizeof(RIFFLIST); WAVEFORMATEX* pFormat = nullptr; BYTE* pWaveStart = nullptr; DWORD waveSize = 0; while (pChunk < pWaveEnd) { if (pChunk + sizeof(RIFFCHUNK) > pWaveEnd) return false; RIFFCHUNK* pCurrent = reinterpret_cast(pChunk); DWORD chunkSize = pCurrent->cb; if (pCurrent->fcc == mmioFOURCC('f', 'm', 't', ' ')) { pFormat = reinterpret_cast(pChunk + sizeof(RIFFCHUNK)); if (pCurrent->cb > sizeof(WAVEFORMATEX)) return false; memcpy(&native_data_.wfx, pFormat, sizeof(WAVEFORMATEX)); } else if (pCurrent->fcc == mmioFOURCC('d', 'a', 't', 'a')) { pWaveStart = pChunk + sizeof(RIFFCHUNK); waveSize = pCurrent->cb; } DWORD padding = (chunkSize % 2) ? 1 : 0; pChunk += sizeof(RIFFCHUNK) + chunkSize + padding; if (pChunk > pWaveEnd) return false; } if (!pFormat || !pWaveStart || !waveSize) return false; native_data_.pData = pWaveStart; native_data_.dwSize = waveSize; return true; } bool sound::create_snd_buffer(const Microsoft::WRL::ComPtr& device) { DSBUFFERDESC dsbd = {}; dsbd.dwSize = sizeof(DSBUFFERDESC); dsbd.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS; dsbd.dwBufferBytes = native_data_.dwSize; dsbd.lpwfxFormat = &native_data_.wfx; if (FAILED(device->CreateSoundBuffer(&dsbd, &sound_buffer_, nullptr))) return false; LPVOID pLocked = nullptr; DWORD dwLockedSize = 0; if (SUCCEEDED(sound_buffer_->Lock(0, 0, &pLocked, &dwLockedSize, nullptr, nullptr, DSBLOCK_ENTIREBUFFER))) { memcpy(pLocked, native_data_.pData, native_data_.dwSize); sound_buffer_->Unlock(pLocked, dwLockedSize, nullptr, 0); } return true; } < /code> Итак, после выполнения этих методов для инициализации звука я выполняю метод воспроизведения звукового объекта и звукового буфера.bool sound::play() { if (!sound_buffer_) return false; sound_buffer_->SetCurrentPosition(0); sound_buffer_->SetVolume(DSBVOLUME_MAX); return sound_buffer_->Play(0, 0, 0) == DS_OK; } [/code] Я получил сбой при достижении этой строки -> return sound_buffer _-> play (0, 0, 0) == ds_ok; и эта проблема появляется только в том случае, если я запускаю проект под адресом.[code]00007FFF81D14CCC je CCommandManager::ParseRegistrationQueue+98h (07FFF81D14D3Ch) 00007FFF81D14CCE mov rdi,qword ptr [rsp+30h] 00007FFF81D14CD3 cmp dword ptr [rdi],0 [/code] rdi равен 0, но я не могу понять, как это возможно, если объекты инициализируются правильно, указатели верны и все выглядит хорошо. Подробнее здесь: [url]https://stackoverflow.com/questions/79547416/calling-play-method-of-directsoundbuffer-object-causes-crash-under-address-sanit[/url]