问题描述
已解决:愚蠢的重新声明问题,我没注意到。
以下完整的异常消息:Exception thrown at 0x00007FF73EB618D7 in Metadata_modifier.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF. occurred
有问题的行:SafeRelease(&pIByteStream);
我正在尝试使用C ++创建一个使用Win32 API的应用程序,以获取媒体文件的元数据(文件的属性,包括“名称”,“#”,“标题”,“贡献者”等)
位于https://docs.microsoft.com/en-us/windows/win32/medfound/shell-metadata-providers的页面列出了实现此目的的3个步骤:
由于它提供了第2步和第3步的代码示例(EnumerateMetadata
),因此我的代码(可以在底部找到完整的代码)专注于尝试实现第1步。
这是我目前正在做的事情的概述:
template <class T> void SafeRelease(T **ppT) {
if (*ppT) {
(*ppT)->Release();
*ppT = NULL;
};
};
...
IMFSourceResolver *pISourceResolver;
IMFByteStream *pIByteStream;
...
HRESULT hr2 = MFCreateSourceResolver(&pISourceResolver);
...
HRESULT hr3 = MFCreateFile(MF_ACCESSMODE_READ,MF_OPENMODE_FAIL_IF_NOT_EXIST,MF_FILEFLAGS_NONE,FileName,&pIByteStream);
...
SafeRelease(&pISourceResolver);
SafeRelease(&pIByteStream);
这里无法接受Exception thrown at 0x00007FF93E507A7A (ntdll.dll) .Access violation reading location 0xFFFFFFFFFFFFFFFF的答案,因为查看完整的代码后,您会看到重复使用if (SUCCEEDED(hr)) {...}
,从而保证了上一个{{ 1}},然后继续设置HRESULT
的值。
话虽如此,我理解为什么会引发此异常,并且对此https://social.msdn.microsoft.com/Forums/vstudio/en-US/1f850f9e-41fd-4178-9da5-a0f568051309/unhandled-exception-at-access-violation-reading-location-?forum=vclanguage的公认答案使我觉得我做错了什么,但我不确定到底是什么。
pIByteStream
和IMFByteStream
都继承自IMFSourceResolver
,因此两者都肯定具有IUnkNown
方法。此外,https://docs.microsoft.com/en-us/windows/win32/api/mfapi/nf-mfapi-mfcreatefile和https://docs.microsoft.com/en-us/windows/win32/api/mfidl/nf-mfidl-mfcreatesourceresolver都针对各自的out参数提到“调用者必须释放接口”,但是Release()
不会引发任何异常。
我尝试使用VS调试代码,但是与SafeRelease(&pISourceResolver);
一起为Source_MF_OBJECT_TYPE
生成了2个本地语言-0x ...和0xcccccccccccccccccc。具有合法地址的地址在地址之后有pIByteStream
,这使我相信它是“好”指针,因为<information not available,no symbols loaded for mfplat.dll>
也具有该地址并且已正确释放,但是特别是该变量是在pISourceResolver
声明行生成(?)的,它在hr3
行之后消失了,我不知道为什么。
我试图根据https://docs.microsoft.com/en-us/windows/win32/medfound/configuring-a-media-source的示例创建代码,但是即使该示例基于MSDN,也不会将2个参数传递给pSource->QueryInterface(...)
(https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-queryinterface(refiid_void)),而我无法找不到IUnkNown::QueryInterface
的文档,但是无论是否包含宏,我的代码都表现出相似的行为。
*我知道这大概是第15个“在...上抛出异常。访问冲突读取位置...”问题在Stack Overflow上发布,答案可能正盯着我,但我一直在尝试现在至少要花一天时间解决这个问题,但我仍然一无所获,因此,如果有人向我指出正确的方向,我将不胜感激。 谢谢。
完整代码:
IID_PPV_ARGS
解决方法
void CreateMediaSource(IMFMediaSource **ppIMediaSource) {
....
IMFByteStream *pIByteStream; // HERE
....
if (SUCCEEDED(hr2)) {
IMFByteStream* pIByteStream; // HERE
HRESULT hr3 = MFCreateFile(MF_ACCESSMODE_READ,MF_OPENMODE_FAIL_IF_NOT_EXIST,MF_FILEFLAGS_NONE,FileName,&pIByteStream);
....
}
SafeRelease(&pIByteStream);
}
您发布的那个甚至都没有初始化。删除第二个声明。