0
안녕하세요 여러분, 저는 지난 며칠 동안이 일에 매달 렸습니다. 내가 캐스팅 할 수있는 사용자 지정 COM 인터페이스가 있지만 함수 포인터 인 경우이 포인터가 변경되었으므로 AccessViolationException이 발생합니다.C에서 사용자 지정 DirectShow 필터 인터페이스를 정렬합니다. #
아래 코드는 마샬링하는 두 인터페이스를 나타냅니다. 모든 방법으로 동일한 문제가 발생합니다.
도움이 될 것입니다.
/*
struct SourceConfig {
LONGLONG llBufferDuration; // The buffer duration to use while receiving samples from the network, measured in 100nsec units
REFERENCE_TIME rtStartTime;
FLOAT fRate; // Negative: rewind, Positive: forward
BYTE btConnectionTimeout; // The time to wait for a connection to be established, measured in seconds
BOOL bKeyFramesOnly;
CHAR pIP[128];
WORD wPort;
CHAR pChannel[64];
BYTE pbtCertificate[96];
SAMPLE_TIME eSampleTime;// Indicates weather to directly route the samples with the absolute UTC
// time OR to make all generated samples relative to zero, default value
// is 'RELATIVE'.
HANDLE hEvent; // Used to wait for the operation completion (optional)
BYTE bAutoSeekToNextAvailPos; // If seeking into a hole automatically resume streaming from the next available position
DWORD dwSampleStarvationTimeout; // The maximal amount of seconds (and not msec) the filter might wait for incoming data
};
interface
__declspec(uuid("{9331DC40-40F5-438a-B9C0-44B479246C98}"))
IStreamingSourceCallback : IUnknown {
virtual STDMETHODIMP OnStreamingSourceEvent(IN STREAMING_SRC_EVENT eCode, IN const VARIANT* pvar1 = 0, IN const VARIANT* pvar2 = 0, IN const VARIANT* pvar3 = 0) = 0;
};
interface
__declspec(uuid("{ECF7715E-E973-4bb9-AEED-389845F0E297}"))
IStreamingSource : IUnknown {
virtual HRESULT GetConfig(OUT SourceConfig* pCfg) = 0;
virtual HRESULT SetConfig(IN const SourceConfig* pCfg) = 0;
virtual HRESULT SetCallback(IN IStreamingSourceCallback* pCallback) = 0;
virtual HRESULT UpdateAbsoluteRefTime(IN LONGLONG& llRefTime) = 0;
virtual HRESULT GetSeekPos(IN OUT REFERENCE_TIME& rtSeek) = 0;
};
*/
public enum SAMPLE_TIME : byte
{
Relative,
Absolute
};
[StructLayout(LayoutKind.Sequential)]
public struct SourceConfig
{
long BufferDuration;
long StartTime;
float Rate;
byte ConnectionTimeout;
[MarshalAs(UnmanagedType.Bool)]
bool KeyFramesOnly;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string Ip;
UInt16 Port;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string Channel;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 96)]
public byte[] Certificate;
SAMPLE_TIME SampleTime;
IntPtr Event;
byte AutoSeekToNextAvailPos;
uint SampleStarvationTimeout;
};
public enum STREAMING_SRC_EVENT : int
{
SRC_NONE,
SRC_CONNECTED,
SRC_DISCONNECTED,
SRC_ERROR,
SRC_STARTTIME,
SRC_STREAM_CLOSE2LIVE,
SRC_STREAM_FAR_LIVE,
SRC_NEARESTSEEK
};
[ComImport, Guid("9331DC40-40F5-438a-B9C0-44B479246C98"), SuppressUnmanagedCodeSecurity, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IStreamingSourceCallback
{
[PreserveSig]
int OnStreamingSourceEvent(
[In, MarshalAs(UnmanagedType.I4)] STREAMING_SRC_EVENT code,
[In, MarshalAs(UnmanagedType.IUnknown)] object var1,
[In, MarshalAs(UnmanagedType.IUnknown)] object var2,
[In, MarshalAs(UnmanagedType.IUnknown)] object var3);
}
[ComImport, Guid("ECF7715E-E973-4bb9-AEED-389845F0E297"), SuppressUnmanagedCodeSecurity, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IStreamingSource
{
[PreserveSig]
int GetConfig([Out, MarshalAs(UnmanagedType.Struct)] out SourceConfig config);
[PreserveSig]
int SetConfig([In, MarshalAs(UnmanagedType.Struct)] SourceConfig config);
[PreserveSig]
int SetCallback([In, MarshalAs(UnmanagedType.Interface)] IStreamingSourceCallback callback);
[PreserveSig]
int UpdateAbsoluteRefTime([In, MarshalAs(UnmanagedType.I8)] ref long refTime);
[PreserveSig]
int GetSeekPos([In, Out, MarshalAs(UnmanagedType.I8)] ref long seekTime);
}
다음 코드는 사용을 보여줍니다 우측 구조
IStreamingSource ssInterface = vosFilter as IStreamingSource;
if (ssInterface == null)
{
throw new ApplicationException("Could not get IStreamingSource. ");
}
if ((hr = ssInterface.SetCallback(_ssCallback)) < 0)
{
throw new ApplicationException("Could not set streaming source callback. " + DirectShowLib.DsError.GetErrorText(hr));
}
ssInterface 포인트, 즉시 SetCallback에 단계별로를,이 쓰레기를 가리 킵니다.
감사합니다.