c#中的编组自定义directshow过滤器接口

时间:2010-01-21 08:55:29

标签: c# com marshalling directshow

嘿伙计们,过去几天我一直坚持这个。我有一个自定义的COM接口,我能够转换为,但当我调用一个如果它的函数我得到一个AccessViolationException,因为这个指针已经改变。

以下代码表示我正在编组的两个接口。所有方法都会导致同样的问题。

非常感谢任何帮助。

/*
    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,这就指向垃圾。

感谢。

1 个答案:

答案 0 :(得分:0)

如果你在SetCallback方法sig中的IStreamingSourceCallback参数上取出MarshalAs(UnmanagedType.Interface),你仍会得到错误吗?