marshalling custom directshow filter interface in c#
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_CONNECT开发者_开发问答ED,
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.
Do you still get the error if you take out the MarshalAs(UnmanagedType.Interface) on the IStreamingSourceCallback argument in your SetCallback method sig?
精彩评论