locked
Mixing c++/Cx code with legacy c++?

    Question

  • I have created a Windows Runtime Component DLL and imported a large chunk of legacy C++.  All of the c++ files in the WRC dll are compiled with the Consume Runtime Extension: "Yes (/ZW)".

    From within a legacy C++ module, I need to be able to reference a class compiled with the C++/CX extension syntax:

            public ref class WASAPIManager sealed

    Can legacy c++ and c++/Cx co-exist in the same Namespace or does it not matter?

    What would be the correct way to create a new instance of the WASAPIManager class from a legacy C++ module?

    Any links, references, suggestions would be appreciate.

    Tuesday, April 28, 2015 11:40 PM

All replies

  • It is common for C++/Cx and standard C++ to coexist in the same module. C++/Cx is often used on the boundaries of a class and standard C++ for the body of the class.

    If you want to consume a ref class from C++ rather than from C++/Cx then you would typically use the Windows Runtime C++ Template Library (WRL).

    Wednesday, April 29, 2015 5:07 AM
    Moderator
  • I have 3 classes as follows (based on code from the MS Wasapi Audio samples) - note all of these classes are compiled in the same Windows Runtime Component assembly with the /ZW flag:

        class LegacyClass {

        public:
            WASAPIManager^ m_wasapiManager;
        ...
        };

        public ref class WASAPIManager sealed
        {
        public:
            ComPtr<WASAPICapture> m_Capture;
        ...
        };

        class WASAPICapture :
            public RuntimeClass< RuntimeClassFlags< ClassicCom >, FtmBase, IActivateAudioInterfaceCompletionHandler >
        {
        public:
            DeviceStateChangedEvent^       m_DeviceStateChanged;
        ...};


    In the Legacy class, we create a reference to WASAPIManager as follows:

            m_wasapiManager = ref new WASAPIManager();


    Then in the WASAPIManager class:

            m_Capture = Make<WASAPICapture>();

            // Get a pointer to the device event interface
            m_StateChangedEvent = m_Capture->GetDeviceStateEvent();

            // Register for events
            m_StateChangedEvent->StateChangedEvent += ref new DeviceStateChangedHandler(this, &WASAPIManager::OnDeviceStateChange);

    However, when something in the WASAPICapture class tries to SetState through the DeviceStateChangedHandler, the WASAPIManager::OnDeviceStateChange never gets called.

    The only difference between my code and the WASAPI Audio samples, is that the Legacy class creates the WASAPIManager class, rather than being instantiated from a Runtime Component.

    I could not figure out how to use ComPtr<> and Make to instantiate the WASAPIManager RuntimeComponent class. Otherwise, the implementation of the WASAPIManager and WASAPICapture follow the sample code.

    UPDATE: the issue with receiving the OnDeviceStateChange seems to be related to some kind of timing issue between the initialization happening on a background thread being blocked for some reason.  Inserting a sleep after the initialization seems to allow the state changed events to bubble up.            

    Thursday, April 30, 2015 3:03 PM