避免在使用WinAPI(Windows Core Audio)时无效的指针
Avoiding invalidated pointers while using WinAPI (Windows Core Audio)
我们使用IMMNotificationClient
的实例化来通知我们特定音频设备(Foo sound blaster(发生的变化,但是当尚未安装在计算机上的Foo冲击波插入时,程序会在IMMNotificationClient::OnDeviceStateChanged
函数内部出现段错误(抛出访问冲突(
据我所知,以下是导致这种情况发生的原因:
- 插入新的 Foo 冲击波
- Windows 向 IMMNotificationClient 触发设备状态更改通知
- 在
IMMNotificationClient::OnDeviceStateChanged
函数可以完成执行之前,Windows 会使 COM 对象失效。
此失效发生在IMMNotificationClient::OnDeviceStateChanged
函数中看似随机的点。
下面是一些示例代码:
#include <mmdeviceapi.h>
#include <functiondiscoverykeys_devpkey.h>
#include <string>
class FooSoundBlasterNotifier: public IMMNotificationClient {
//private member variables
const char * FOO_BLASTER_NAME = "Foo Blaster";
public:
HRESULT STDMETHODCALLTYPE OnDeviceStateChanged(LPCWSTR pDeviceId, DWORD newState)
{
IMMDeviceEnumerator *pDeviceEnumerator;
IMMDevice *pDevice;
IPropertyStore *pStore;
HRESULT hr = CoInitialize(NULL);
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pDeviceEnumerator);
if(SUCCEEDED(hr))
{
hr = pDeviceEnumerator->GetDevice(pDeviceId, &pDevice);
if(SUCCEEDED(hr))
{
hr = pDevice->OpenPropertyStore(STGM_READ, &pStore);
if (SUCCEEDED(hr))
{
PROPVARIANT variant;
PropVariantInit(&variant);
hr = pStore->GetValue(PKEY_Device_FriendlyName, &variant);
if (SUCCEEDED(hr))
{
//Code usually crashes about right here
std::wstring friendlyNameW(variant.pwszVal);
std::string friendlyName(friendlyNameW.begin(), friendlyNameW.end());
if(friendlyName.find(FOO_BLASTER_NAME) != std::string::npos)
{
//Log the information about state change
}
//release
}
//all
}
//COM
}
//Objects
}
return S_OK;
}
//Declare other needed functions
};
如何避免使用无效的 Windows COM 对象?除此之外,我如何从访问冲突中成功恢复而无需关闭整个程序?
编辑
下面是代码失败位置的调用跟踪:
common_strnlen_simd<1,1,unsigned short>(const unsigned short * const string, const unsigned __int64 maximum_count) Line 152
at minkernelcrtsucrtsrcappcrtstringstrnlen.cpp(152)
common_strnlen<1,unsigned short>(const unsigned short * const string, const unsigned __int64 maximum_count) Line 185
at minkernelcrtsucrtsrcappcrtstringstrnlen.cpp(185)
wcslen(const wchar_t * string) Line 219
at minkernelcrtsucrtsrcappcrtstringstrnlen.cpp(219)
[External Code]
FooSoundBlaster::OnDeviceStateChanged(const wchar_t * pwstrDeviceId, unsigned long dwNewState)
[External Code]
真正的问题不是IMMDevice对象的无效,而是variant.pwszVal
为空。像这样的简单检查:
if(variant.pwszVal /* != NULL, there you go Paul! :) */)
{
friendlyNameW = variant.pwszVal;
}
应该解决上面代码中的问题。
相关文章:
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 无法访问嵌套类.类的使用无效
- 如果用户输入无效,如何使用字符串变量-C++重复输入命令
- 如何解决错误:SCIP C++中的 SCIP 阶段无效 <10>
- 在没有参数列表的情况下使用模板名称"Event"无效,模板问题
- FFMPEG配置文件级别id大小无效
- 错误:从"int"到枚举c++的转换无效
- 如何修复此错误:className::className的无效使用
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- C++-模板嵌套类的引用初始化无效
- 错误:无效的预处理指令 #i 的意思是 #if?
- 多维数组 C++ 中数组下标的类型"int[int]"无效
- 在 C++ 中使用正则表达式错误时出现问题 括号表达式中的范围无效
- 从 'int' 到 'int*' CPP 的转换无效
- 如何接受 [ENTER] 键作为无效输入并发送错误消息
- 由于无效的 ValidateRgn() 子窗口不会收到WM_PAINT消息
- C++ PTHREADS - 无效转换无效*(*)()到无效*(*)(无效*)
- 声明为无效的变量或字段'...' Ardunio 编译器上的错误
- 数组下标的类型"float*[float]"无效
- 避免在使用WinAPI(Windows Core Audio)时无效的指针