在 IMMDeviceEnumerator 上调用 SAFE_RELEASE 时崩溃
Crash when SAFE_RELEASE is called on IMMDeviceEnumerator
>我正在使用服务来检测头组的连接。当麦克风连接和断开连接时,我会收到通知。问题是,当我手动结束服务时,我在做SAFE_RELEASE时面临服务崩溃。这是代码...
NotifyHandsetConnectionStatus::NotifyHandsetConnectionStatus() : _cRef(1), _pEnumerator(NULL){}
NotifyHandsetConnectionStatus::~NotifyHandsetConnectionStatus()
{
// SAFE_RELEASE(_pEnumerator)
if (_pEnumerator)
{
_pEnumerator->Release(); // CRASH
_pEnumerator = NULL;
}
}
void NotifyHandsetConnectionStatus::Init(DWORD threadID)
{
PTTThreadID = threadID;
HRESULT hr = S_OK;
CoInitialize(NULL);
if (_pEnumerator == NULL)
{
// Get enumerator for audio endpoint devices.
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER,
__uuidof(IMMDeviceEnumerator), (void**)&_pEnumerator);
}
if (hr == S_OK)
{
_pEnumerator->RegisterEndpointNotificationCallback(this);
}
}
这是类声明...
class NotifyHandsetConnectionStatus : public IMMNotificationClient
{
LONG _cRef;
IMMDeviceEnumerator *_pEnumerator;
DWORD PTTThreadID;
public:
NotifyHandsetConnectionStatus();
~NotifyHandsetConnectionStatus();
void Init(DWORD threadID);
ULONG STDMETHODCALLTYPE AddRef() override;
virtual ULONG STDMETHODCALLTYPE Release() override;
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, VOID **ppvInterface) override;
HRESULT STDMETHODCALLTYPE OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState) override;
HRESULT STDMETHODCALLTYPE OnDeviceAdded(LPCWSTR pwstrDeviceId) override
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE OnDeviceRemoved(LPCWSTR pwstrDeviceId) override
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key) override
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged( EDataFlow flow, ERole role, LPCWSTR pwstrDeviceId) override
{
return S_OK;
}
};
您发布的代码不会崩溃,即使没有取消注册回调也不会崩溃。 通过复制粘贴您拥有的内容并添加您没有的内容来检查。 IUnknow的方法丢失了,但不太可能与它有任何关系。 只要确保你的 Release() 函数不会被频繁调用,delete this
只工作一次。
像这样的代码崩溃的原因有很多,堆损坏是每个C++程序员讨厌的大声邻居,他永远最有可能在最不合时宜的时刻出现。 由于程序退出很可能是让邻居将拨盘转到 11 的时间,这是您触摸一段时间不需要的堆部分的时候。 很难调试,损坏发生得更早。
隔离问题,首先将服务转换为执行所有相同动作的控制台模式应用,以便更易于调试。 您可以使用堆诊断工具,如 UMHD.exe。 为单个代码块编写单元测试。
似乎
需要Unregister the IMMDeviceEnumerator before calling Release()
.
_pEnumerator->UnregisterEndpointNotificationCallback(this);
相关文章:
- 当回溯以零开始时,如何调试崩溃
- 内联映射初始化的动态atexit析构函数崩溃
- 执行函数时导致崩溃的变量
- 程序崩溃并显示"std::out_of_range"错误
- CoInitialize()在单独的线程上崩溃而不返回
- 使用调试/崩溃报告将应用程序部署到客户端
- 为什么所有C++编译器都会崩溃或挂起此代码
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- 为什么我的多线程作业队列崩溃
- ExtractIconEx:可以工作,但偶尔会崩溃
- 为什么引用传递会导致此崩溃(C++)
- 试图创建流或fopen时程序崩溃
- 类对象数组的问题会导致崩溃
- 排序时无法执行交换操作.我做的时候它会崩溃.为什么
- 为什么要增加导致崩溃的指针
- 在虚幻引擎中删除NXOpen对象时崩溃
- 为什么它只打印双链接列表的第一个值,而我的程序却崩溃了
- 为什么 std::make_unique<std::thread>(somefun()) 会在我没有调用 release() 时生成崩溃,并且在调用时会生成崩溃?
- C++Visual Studio Release生成未使用的代码崩溃
- 在RELEASE配置中使用向量push_back时,C++代码崩溃