Hey folks, I've been stuck on this for the past few days. I have a custom COM interface that I am able to cast to, but when I call one if it's functions I get an AccessViolationException because the this pointer has changed.
The below code represents the two interfaces that I am marshalling. All methods result in the same problem.
Any help will be greatly appreciated.
/*
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);
}
The following code shows the usage:
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 points to the right structure, as soon as stepping through to SetCallback, this points to garbage.
Thanks.