我正在C#上编写DirectShow过滤器,我不想使用任何第三方库。此任务几乎100%基于正确的COM接口原型,如IGraphBuilder,IBaseFilter,IPin等。如果接口原型不正确,则会抛出托管/本地边界的各种异常。问题是确定错误原型接口方法的位置。
目前我有: DirectShow.dll中出现类型'System.NullReferenceException'的异常(这是我的托管dll的名称),并且在托管/本地边界之前未处理
调用堆栈:
ntdll.dll!NtWaitForSingleObject()+ 0xa bytes
KernelBase.dll!WaitForSingleObjectEx()+ 0x9c bytes
clr.dll!CLREvent :: WaitEx()+ 0x20f bytes
clr.dll!CLREvent :: WaitEx()+ 0x1b8 bytes
clr.dll!CLREvent :: WaitEx()+ 0x73 bytes
clr.dll!Thread :: WaitSuspendEventsHelper()+ 0xcf bytes clr.dll!Thread :: WaitSuspendEvents()+ 0x10 bytes
clr.dll!string“d:\ iso_whid \ amd64fre \ base \ ntos \ r \ n”...()+ 0x35688d字节
clr.dll!Thread :: RareDisablePreemptiveGC()+ 0x118 bytes
clr.dll!GCHolderEEInterface< 0,0,0> ::〜GCHolderEEInterface< 0,0,0>()+ 0x19 bytes clr.dll!Debugger :: SendCatchHandlerFound()+ 0x150 bytes
clr.dll!string“d:\ iso_whid \ amd64fre \ base \ ntos \ r”...()+ 0x3b9340 bytes
clr.dll!NotifyOfCHFFilterWrapper()+ 0x77字节
clr.dll!string“d:\ iso_whid \ amd64fre \ base \ ntos \ r \ n”...()+ 0x336941字节
msvcr100_clr0400.dll!__ C_specific_handler()+ 0x97字节
ntdll.dll!RtlpExecuteHandlerForException()+ 0xd bytes ntdll.dll!RtlDispatchException()+ 0x38f字节 ntdll.dll!KiUserExceptionDispatch()+ 0x2e bytes
KernelBase.dll!RaiseException()+ 0x3d bytes
clr.dll!NakedThrowHelper2()+ 0xc bytes
clr.dll!NakedThrowHelper_RspAligned()+ 0x3d bytes clr.dll!NakedThrowHelper_FixRsp()+ 0x5 bytes
000007ff00179486()
clr.dll!COMToCLRDispatchHelper()+ 0x4e bytes
clr.dll!SecurityDeclarative :: CheckLinkDemandAgainstAppDomain() - 0x40e bytes
clr.dll!COMToCLRWorkerBody()+ 0xd6 bytes
clr.dll!COMToCLRWorkerDebuggerWrapper()+ 0x22字节
clr.dll!COMToCLRWorker()+ 0x201字节 clr.dll!GenericComCallStub()+ 0x57字节
[原产于管理过渡]
quartz.dll!CEnumConnectedPins :: CEnumConnectedPins()+ 0x4a bytes
quartz.dll!CFilterGraph :: FindUpstreamInterface()+ 0x150字节 quartz.dll!CFilterGraph :: FindUpstreamInterface()+ 0xc1 bytes
quartz.dll!CFilterGraph :: FindUpstreamInterface()+ 0x171字节 quartz.dll!CFilterGraph :: FindUpstreamInterface()+ 0xc1 bytes
quartz.dll!CFilterGraph :: FindUpstreamInterface()+ 0x171字节 quartz.dll!CFilterGraph :: FindUpstreamInterface()+ 0xc1 bytes
quartz.dll!CWaveSlave :: UpdateSlaveMode()+ 0xa7 bytes
quartz.dll!CWaveOutInputPin :: RemovePreroll()+ 0x95 bytes
quartz.dll!CWaveOutInputPin :: Receive()+ 0x12f bytes
msmpeg2adec.dll!CBaseOutputPin :: Deliver()+ 0x22字节 msmpeg2adec.dll!CIVIAudioFilter :: DeliverOutSample()+ 0x3da bytes
msmpeg2adec.dll!CIVIAudioCodec :: DecodeDDPlus()+ 0x556 bytes
msmpeg2adec.dll!CIVIAudioCodec :: DecodeAll()+ 0x121 bytes
msmpeg2adec.dll!CIVIAudioFilter :: Process()+ 0xda7 bytes
msmpeg2adec.dll!CIVIAudioFilter :: Receive()+ 0x16d bytes
msmpeg2adec.dll!CTransformInputPin :: Receive()+ 0x4c字节 msmpeg2adec.dll!CIVIAudioInPin :: Receive()+ 0x3f字节 quartz.dll!CBaseOutputPin :: Deliver()+ 0x22 bytes
quartz.dll!CBaseMSRWorker :: TryDeliverSample()+ 0x14f bytes
quartz.dll!CBaseMSRWorker :: PushLoop()+ 0x1da bytes
quartz.dll!CBaseMSRWorker :: ThreadProc()+ 0x90 bytes
quartz.dll!CAMThread :: InitialThreadProc()+ 0x1c字节 kernel32.dll!BaseThreadInitThunk()+ 0xd bytes ntdll.dll!RtlUserThreadStart()+ 0x21 bytes
换句话说,管道是:
所以这不会让我在任何地方,我不知道如何调试。
答案 0 :(得分:3)
非常难以调试,失败发生在你没写的代码中。慢一点来诊断这个。编写一个本机测试程序,获取要测试的接口指针,并按v表顺序逐个验证方法。坏的会弹出来。
请注意C#不支持多重继承。从非IUnknown或IDispatch的另一个接口继承的任何COM接口都要求您重复基接口中方法的声明。忘记这样做会导致调用错误的方法。或者由于v表太短而不存在。 NullReference或AccessViolation是一个常见的结果。