callback function in mci


  • Hi all,

    I want to implement MCI with a custom IOProc() as explained in the article .
    The IOProc will be used as callback in the method :  mmioInstallIOProc(.........., (LPMMIOPROC) IOProc, .......); such this.

    I have written this : 

    private static extern int mmioInstallIOProc(
    int fourcc,
    MarshalAs(UnmanagedType.FunctionPtr)] MulticastDelegate ptrFunc,
    int dwFlags);

    // lpData is a pointer to video data in memory and is used in IOProc()
    byte[] bytedata = System.IO.File.ReadAllBytes(@"video.avi");
    IntPtr ptrData = Marshal.AllocHGlobal(bytedata.Length);
    Marshal.Copy(bytedata, 0, ptrData, bytedata.Length);
    lpData = ptrData.ToInt32();

    private delegate int IOProcType(LPMMIOINFO lpMMIOInfo, uint uMsg, int lParam1, int lParam2);

    mmioInstallIOProc(fourcc, new IOProcType(IOProc), MMIO_INSTALLPROC | MMIO_GLOBALPROC)

    int IOProc(LPMMIOINFO lpMMIOInfo, uint uMsg, int lParam1, int lParam2)
    bool alreadyOpened = false;
    switch (uMsg)
    case MMIOM_OPEN:
    if (alreadyOpened) return 0;
                alreadyOpened =
                lpMMIOInfo.lDiskOffset = 0;
    return 0;
    case MMIOM_CLOSE:
    return 0;
    case MMIOM_READ:
                CopyMemory(lParam1, lpData + lpMMIOInfo.lDiskOffset, lParam2);
                lpMMIOInfo.lDiskOffset += lParam2;
    return lParam2;
    return -1;

    When I run with other required methods it enters IOProc() with MMIOM_OPEN, MMIOM_CLOSE and MMIOM_READ several times for each but mciSendString("open test+ type avivideo", null, 0, null); return error. Error says: MCI cannot open and play this file type. But it can I know, MCI plays it when play from file.

    What may be the source of this problem? May be about calling conventions for example?


    • Edited by noanyx Tuesday, September 2, 2008 5:58 PM added extra information
    • Moved by Peter RitchieModerator Tuesday, September 2, 2008 6:44 PM Question not specific to C# language (Moved from Visual C# Language to Visual C# General)
    Tuesday, September 2, 2008 5:50 PM


  • Using new IOProcType(IOProc) int the method call is not correct.  The .NET garbage collector doesn't know that unmanaged code is using the delegate, the next collection will crash your program.  Store it in a class member so it will live at least as long as you keep the callback installed.

    But you didn't get this far yet.  The fourcc value is critical, did you pass the correct one?  alreadyOpened doesn't look great.  You'd better check if it doesn't call SEEK, it almost certainly will.  You are not indicating end-of-file correctly, always passing as many bytes as it asks for.

    Hans Passant.
    Wednesday, September 3, 2008 3:12 AM