Delphi中DirectShow自定义Filter建图时访问违例问题排查
DirectShow自定义Filter过滤器图构建异常解决
异常信息
Project Project1.exe触发AEccessViolation异常,消息为:“模块'Project1.exe'中地址0045AAA8处发生访问违例,读取地址00000000”。进程已停止,可使用单步或继续运行操作。
问题定位
调试确认错误出在GetUnconnectedPin函数的hr:= pFilter.EnumPins(pEnum);语句,本质是**pFilter为空指针**,导致访问内存地址00000000触发异常。
修复方案及排查步骤
1. 验证自定义Filter的注册与CLSID正确性
- 用
regsvr32.exe重新注册Filter的DLL,确认无注册报错 - 核对代码中使用的Filter CLSID,必须与Filter实现代码中定义的GUID完全一致,注意大小写和格式
2. 检查Filter实例创建流程
- 在调用
CoCreateInstance创建Filter实例后,立即检查返回值hr是否为S_OK,确保实例创建成功:var pFilter: IBaseFilter; hr: HRESULT; begin hr := CoCreateInstance(CLSID_YourCustomFilter, nil, CLSCTX_INPROC_SERVER, IID_IBaseFilter, pFilter); if Failed(hr) then begin ShowMessage('Filter创建失败,错误码: ' + IntToHex(hr, 8)); Exit; end; // 后续将pFilter传入GetUnconnectedPin等函数 end; - 若创建失败,排查Filter DLL的依赖库(用Dependency Walker工具),或确认平台匹配(32位/64位需与项目一致)
3. 修复GetUnconnectedPin函数的指针校验
在调用EnumPins前增加空指针判断,提前拦截非法调用:
function GetUnconnectedPin(pFilter: IBaseFilter; out pPin: IPin; Direction: PIN_DIRECTION): HRESULT; var pEnum: IEnumPins; hr: HRESULT; pCurrentPin: IPin; pcFetched: Cardinal; pinDir: PIN_DIRECTION; begin Result := E_FAIL; pPin := nil; // 新增空指针校验 if not Assigned(pFilter) then begin Exit; end; hr := pFilter.EnumPins(pEnum); if Failed(hr) then begin Exit; end; // 后续枚举Pin并查找未连接Pin的逻辑... while pEnum.Next(1, pCurrentPin, pcFetched) = S_OK do begin pCurrentPin.QueryDirection(pinDir); if pinDir = Direction then begin if pCurrentPin.ConnectedTo(nil) = VFW_E_NOT_CONNECTED then begin pPin := pCurrentPin; Result := S_OK; Break; end; end; pCurrentPin := nil; end; end;
4. 排查指针传递环节
- 回溯
GetUnconnectedPin的调用链,确认传入的pFilter在传递过程中未被意外释放或赋值为nil - 避免在Filter实例创建后未添加到过滤器图就提前释放接口指针(COM接口指针需保证引用计数正确)
内容的提问来源于stack exchange,提问作者Legat
相关产品推荐
相关产品推荐

