locked
Unmanaged C++ callback to C# delegate problem RRS feed

  • Question

  • I'm using an unmanaged c++ dll in my c# project. This dll controls a compression card on my PC. I'm trying to use a method from it. Dll signature is like that;

     

    Start Video Capture

    API:

    int StartVideoCapture(HANDLE hChannelHandle)

    Parameters:

    HANDLE hChannelHandle : Channel Handle

    Remarks:

    Start Video Capture, then the video and audio stream data will be returned in the callback function StreamDirectReadCallback() which is registered by the function RegisterStreamDirectReadCallback.

    Register Stream Direct Read Callback Function

    API:

    int RegisterStreamDirectReadCallback(STREAM_DIRECT_READ_CALLBACK StreamDirectReadCallback, void *Context)

    Parameters:

    STREAM_ DIRECT _READ_CALLBACK StreamDirectReadCallback : When the stream data is ready, this function will be called automatically

    Void *Context : Context when this function is called

    Callback function Explanation:

    STREAM_DIRECT_READ_CALLBACK (ULONG channelNumber, void *DataBuf, DWORD Lenght, int FrameType, void *context)

    ULONG channelNumber : Channel Number

    Void *DataBuf : Address of data buffer

    DWORD Length : Length of data buffer

    int FrameType : Current encoding frame type

    void *context : context

     

     

    And I'm calling this method like this;

     

     

    public delegate Int32 STREAM_DIRECT_READ_CALLBACK(UInt32 channelNumber, IntPtr DataBuf, UInt32 Length, Int32 FrameType, IntPtr context);

    [DllImport("DS40xxSDK.dll")]

    public static extern Int32 RegisterStreamDirectReadCallback(STREAM_DIRECT_READ_CALLBACK StreamDirectReadCallback, IntPtr Context);

    [DllImport("DS40xxSDK.dll")]

    public static extern Int32 StartVideoCapture(UIntPtr hChannelHandle);


    STREAM_DIRECT_READ_CALLBACK sdrc = new STREAM_DIRECT_READ_CALLBACK(StreamDirectRead);

    GCHandle sdrcHandle = GCHandle.Alloc(sdrc);

    RegisterStreamDirectReadCallback(sdrc, IntPtr.Zero);

    StartVideoCapture(ChannelHandle[0]);


    public int StreamDirectRead(uint channelNumber, IntPtr DataBuf, uint Length, int FrameType, IntPtr context)

    {

     

                Console.WriteLine("channelNumber=" + channelNumber);

                Console.WriteLine("DataBuf=" + DataBuf);

                Console.WriteLine("Lenght=" + Length);

                Console.WriteLine("FrameType=" + FrameType);

                Console.WriteLine("context=" + context);

     

              return 0;

    }

     

    Sample Output:

     

    channelNumber=0

    DataBuf=159645704

    Lenght=40

    FrameType=128

    context=0

     

     

    When it runs i see the output for once in the console and after that vshost32.exe crashes. Where am i doing a mistake? Please help!!!

     

     

    • Edited by Tempeck81 Friday, October 8, 2010 2:10 PM
    Tuesday, October 5, 2010 9:19 AM

Answers

  • OK. I solved the problem!!!!

    I put [UnmanagedFunctionPointer(CallingConvention.Cdecl)] before public delegate Int32 STREAM_DIRECT_READ_CALLBACK(UInt32 channelNumber, IntPtr DataBuf, UInt32 Length, Int32 FrameType, IntPtrcontext);

    and working great now.

     

            [UnmanagedFunctionPointer(CallingConvention.Cdecl)]

            public delegate Int32 STREAM_DIRECT_READ_CALLBACK(UInt32 channelNumber, IntPtr DataBuf, UInt32 Length, Int32 FrameType, IntPtr context);

            [DllImport("DS40xxSDK.dll")]

            public static extern Int32 RegisterStreamDirectReadCallback(STREAM_DIRECT_READ_CALLBACK StreamDirectReadCallback, IntPtr Context);

     

            [DllImport("DS40xxSDK.dll")]

            public static extern int StartVideoCapture(UIntPtr hChannelHandle);

    • Marked as answer by Tempeck81 Friday, October 8, 2010 2:24 PM
    Friday, October 8, 2010 2:24 PM

All replies

  • Are you sure the callback is supposed to return an int?
    Tuesday, October 5, 2010 9:58 AM
  • I have a working demo project written in C++ ,using this dll. There it returns int.

    typedef int (*STREAM_DIRECT_READ_CALLBACK)(ULONG channelNumber,void *DataBuf,DWORD Length,int FrameType,void *context);

    Tuesday, October 5, 2010 10:17 AM
  • The GC has released the delegate you passed to the function.

    If StartVideoCapture is asynchronous, you need to store the delegate somewhere until it is no longer needed.

    If it is synchronous, it may be released because the variable holding it is not apparently used after the call to RegisterStreamDirectCallback.
    Add

    GC.KeepAlive(sdrc);
    after the StartVideoCapture call.

    Tuesday, October 5, 2010 11:35 AM
  • I tried GC.KeepAlive but problem is not solved.

    In Project Properties-> Debug I checked "Enable unmanaged code debugging" checkbox. Vshost32.exe is not crashing now, but i get an error below;

    Unhandled exception at 0x00000001 in SecurityDVR.exe: 0xC0000005: Access violation.

     

    I couldn't try storing delegate somewhere because I don't know how to do. Can you explain a bit?

    Friday, October 8, 2010 8:53 AM
  • OK. I solved the problem!!!!

    I put [UnmanagedFunctionPointer(CallingConvention.Cdecl)] before public delegate Int32 STREAM_DIRECT_READ_CALLBACK(UInt32 channelNumber, IntPtr DataBuf, UInt32 Length, Int32 FrameType, IntPtrcontext);

    and working great now.

     

            [UnmanagedFunctionPointer(CallingConvention.Cdecl)]

            public delegate Int32 STREAM_DIRECT_READ_CALLBACK(UInt32 channelNumber, IntPtr DataBuf, UInt32 Length, Int32 FrameType, IntPtr context);

            [DllImport("DS40xxSDK.dll")]

            public static extern Int32 RegisterStreamDirectReadCallback(STREAM_DIRECT_READ_CALLBACK StreamDirectReadCallback, IntPtr Context);

     

            [DllImport("DS40xxSDK.dll")]

            public static extern int StartVideoCapture(UIntPtr hChannelHandle);

    • Marked as answer by Tempeck81 Friday, October 8, 2010 2:24 PM
    Friday, October 8, 2010 2:24 PM