gpt4 book ai didi

c++ - 异常抛出...访问冲突读取位置

转载 作者:行者123 更新时间:2023-12-02 09:59:24 29 4
gpt4 key购买 nike

已解决:我没有注意到我这边的愚蠢的重新声明问题。
完整的异常消息如下: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 个步骤:

  1. Get a pointer to the IMFMediaSource interface of the media source. You can use the IMFSourceResolver interface to get an IMFMediaSource pointer.
  2. Call MFGetService on the media source to get a pointer to the IPropertyStore interface. In the guidService parameter of MFGetService, specify the value MF_PROPERTY_HANDLER_SERVICE. If the source does not support the IPropertyStore interface, MFGetService returns MF_E_UNSUPPORTED_SERVICE.
  3. Call IPropertyStore methods to enumerate the metadata properties.

由于它提供了第 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)) {...} , 保证前 HRESULT 的成功在继续设置 pIByteStream 的值之前.
话虽如此,我了解为什么会引发此异常以及对此 https://social.msdn.microsoft.com/Forums/vstudio/en-US/1f850f9e-41fd-4178-9da5-a0f568051309/unhandled-exception-at-access-violation-reading-location-?forum=vclanguage 的公认答案导致我认为我做错了什么,但我不确定到底是什么。
两个 IMFByteStreamIMFSourceResolver继承自 IUnknown ,所以两者肯定都有 Release()方法。此外, https://docs.microsoft.com/en-us/windows/win32/api/mfapi/nf-mfapi-mfcreatefilehttps://docs.microsoft.com/en-us/windows/win32/api/mfidl/nf-mfidl-mfcreatesourceresolver提到相应输出参数的“调用者必须释放接口(interface)”,但 SafeRelease(&pISourceResolver);不抛出任何异常。
我曾尝试使用 VS 调试代码,但与 Source_MF_OBJECT_TYPE 一起使用, 为 pIByteStream 生成 2 个局部变量- 0x... 和 0xcccccccccccccccc。地址看起来合法的地址为 <Information not available, no symbols loaded for mfplat.dll>在地址之后,这让我相信它是“好”指针,因为 pISourceResolver也有它并且它被正确释放,但该变量特别是在 hr3 处生成(?)声明行,它在 pSource->QueryInterface(...) 之后消失了线,我不知道为什么。
我试图将我的代码基于 https://docs.microsoft.com/en-us/windows/win32/medfound/configuring-a-media-source 中的示例但即使该示例不在 MSDN 中,它也不会将 2 个参数传递给 IUnknown::QueryInterface ( https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-queryinterface(refiid_void) ),我找不到 IID_PPV_ARGS 的文档但我发现无论我是否包含宏,我的代码的行为都相似。
*我知道这可能是 Stack Overflow 上发布的无数“异常抛出...访问冲突读取位置...”问题,答案可能正盯着我看,但我一直在努力解决问题至少已经过了一天,我仍然没有得到任何东西,所以如果有人指出我正确的方向,我将不胜感激。
谢谢。
完整代码:
#include <iostream>
#include <Windows.h>
#include <mfidl.h>
#include <mfobjects.h>
#include <mfapi.h>
#include <Unknwn.h>
#include <wtypes.h>
#include <propsys.h> // IPropertyStore
// Mf.lib
// Mfplat.lib

template <class T> void SafeRelease(T **ppT) {
if (*ppT)
{
(*ppT)->Release();
*ppT = NULL;
}
}

HRESULT EnumerateMetadata(IMFMediaSource *pSource) {
IPropertyStore *pProps = NULL;

HRESULT hr = MFGetService(
pSource, MF_PROPERTY_HANDLER_SERVICE, IID_PPV_ARGS(&pProps));

if (SUCCEEDED(hr)) {
DWORD cProps;
hr = pProps->GetCount(&cProps);

if (SUCCEEDED(hr)) {
for (DWORD i = 0; i < cProps; i++) {
PROPERTYKEY key;
hr = pProps->GetAt(i, &key);

if (SUCCEEDED(hr)) {
PROPVARIANT pv;
hr = pProps->GetValue(key, &pv);

if (SUCCEEDED(hr)) {
//DisplayProperty(key, pv);
PropVariantClear(&pv);
};
};
};
};
};

SafeRelease(&pProps);
return hr;
};

void CreateMediaSource(IMFMediaSource **ppIMediaSource) {
PCWSTR FileName = L"C:\\Users\\dlp\\1.mp3";

IUnknown *pSource;
IMFSourceResolver *pISourceResolver;
IMFByteStream *pIByteStream;
MF_OBJECT_TYPE Source_MF_OBJECT_TYPE;

HRESULT hr0 = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
HRESULT hr1 = MFStartup(MF_VERSION);

HRESULT hr2 = MFCreateSourceResolver(&pISourceResolver);

if (SUCCEEDED(hr2)) {
IMFByteStream* pIByteStream;
MF_OBJECT_TYPE Source_MF_OBJECT_TYPE;

HRESULT hr3 = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, FileName, &pIByteStream);

if (SUCCEEDED(hr3)) {
HRESULT hr4 = pISourceResolver->CreateObjectFromByteStream(pIByteStream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL, &Source_MF_OBJECT_TYPE, &pSource);

if (SUCCEEDED(hr4)) {
pSource->QueryInterface(ppIMediaSource);
};
};
};
SafeRelease(&pISourceResolver);
SafeRelease(&pIByteStream);
}

int main() {
IMFMediaSource *IMediaSource = NULL;
CreateMediaSource(&IMediaSource);
EnumerateMetadata(IMediaSource);

return 0;
};```

最佳答案

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);
}
您发布的那个甚至没有初始化。删除第二个声明。

关于c++ - 异常抛出...访问冲突读取位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63421458/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com