Tech Off Thread

3 posts

Writing a managed version of ICreateDevEnum

Back to Forum: Tech Off
  • cosminb

    I have the following interface from "strmif.h" (DirectShow stuff):

        MIDL_INTERFACE("29840822-5B84-11D0-BD3B-00A0C911CE86")
        ICreateDevEnum : public IUnknown
        {
        public:
            virtual HRESULT STDMETHODCALLTYPE CreateClassEnumerator(
                /* [in] */ REFCLSID clsidDeviceClass,
                /* [out] */ IEnumMoniker **ppEnumMoniker,
                /* [in] */ DWORD dwFlags) = 0;
           
        };

    I have found it described in C# like this (in a project called DShow.NET):

        [ComVisible(true), ComImport,
        Guid("29840822-5B84-11D0-BD3B-00A0C911CE86"),
        InterfaceType( ComInterfaceType.InterfaceIsIUnknown )]
    public interface ICreateDevEnum
    {
            [PreserveSig]
        int CreateClassEnumerator(
            [In]                                            ref Guid            pType,
            [Out]                                        out UCOMIEnumMoniker    ppEnumMoniker,
            [In]                                            int                    dwFlags );
    }

    The generated MSIL for the function is:

    .method public hidebysig newslot abstract virtual
            instance int32  CreateClassEnumerator([in] valuetype [mscorlib]System.Guid& pType,
                                                  [out] class [mscorlib]System.Runtime.InteropServices.UCOMIEnumMoniker& ppEnumMoniker,
                                                  [in] int32 dwFlags) cil managed preservesig
    {
    } // end of method ICreateDevEnum::CreateClassEnumerator


    And now my question is: How to represent this interface in C++/CLI? I use VS2005, and tried several times, but it doesn't compile. I am stuck on the IEnumMoniker parameter, don't know how to declare it.

    Does anyone have an idea on how to write this interface in C++/CLI, so that I am able to cast the COM server 'SystemDeviceEnum' to the interface 'ICreateDevEnum'?

    Thanks,
    Cosmin

  • cosminb

    Actually the whole problem reduces to being able to pass an interface as a parameter to a function:

    namespace InterfaceTest
    {

        public interface class Intf
        {
            void Read();
        };

        public ref class Class1
        {
            void Something(Intf i)
            {
            }
        };

    }


    This yields on the function 'Something':

    error C3149: 'InterfaceTest::Intf' : cannot use this type here without a top-level '^'

    Thanks

  • Sven Groot

    cosminb wrote:
    namespace InterfaceTest
    {

        public interface class Intf
        {
            void Read();
        };

        public ref class Class1
        {
            void Something(Intf i)
            {
            }
        };

    }

    The change is in red:

    namespace InterfaceTest
    {

        public interface class Intf
        {
            void Read();
        };

        public ref class Class1
        {
            void Something(Intf ^i)
            {
            }
        };

    }

    EDIT: Since the original interface takes a double pointer to the interface, you're probably going to need "void Something(Intf ^%i)" there to pass a tracking reference to the managed pointer.

Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.