locked
What is the best way to get a callback from an instance of a native C++ class to a C++ ref class?

    Question

  • I am writing a C++ WinRT Component DLL for use in my .NET-based WinRT application. The DLL defines a SoundSample ref class that creates an XAudio voice by calling IXAudio2::CreateSourceVoice. CreateSourceVoice takes a "IXAudio2VoiceCallback *pCallback" parameter to enable callbacks on various audio events. Now I am trying to implement that callback based on this article. XAudio will supposedly just call back into methods of my SoundCallback class defined as:

    #pragma once
    #include "xaudio2.h"
    #include "pch.h"
    
    class SoundCallback
        : public IXAudio2VoiceCallback
    {
    private:
        //SoundSample^ sample; //does not compile
    
    public:
        SoundCallback(void);
        ~SoundCallback(void);
    
        //Called when the voice has just finished playing a contiguous audio stream.
        void OnStreamEnd();
        void OnVoiceProcessingPassEnd();
        void OnVoiceProcessingPassStart(UINT32 SamplesRequired);
        void OnBufferEnd(void * pBufferContext);
        void OnBufferStart(void * pBufferContext);
        void OnLoopEnd(void * pBufferContext);
        void OnVoiceError(void * pBufferContext, HRESULT Error);
    };
    

    Everything is fine until I try to figure out how to call back from an instance of my native callback class to the parent SoundSample object. I was thinking I could pass an instance of the SoundSample class to the SoundCallback object, but it seems like it does not allow me to declare a ref class field in the native class:

    SoundCallback.h(9): error C2143: syntax error : missing ';' before '^'

    SoundCallback.h(9): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

    SoundCallback.h(9): error C3699: '^' : cannot use this indirection on type 'int'

    I looked back at implementing callbacks in native C++ and I could not find a reasonable solution so far. What is the best/easiest way to do this?


    Filip Skakun

    Tuesday, April 3, 2012 5:58 AM

Answers

  • Solved it (thanks to Jeremiah Morrill) - the problem is not with any barrier blocking the use of ref classes in basic classes. C4430 means that SoundSample is an unrecognized type, which was hidden by Intellisense - since that seemed to indicate that SoundSample is known. What needs to be added is a declaration of the SoundSample type and this all starts working fine.

    I just added

    namespace MyNamespace { ref class SoundSample; }

    before the SoundCallback class declaration and then SoundCallback class could declare:

    MyNamespace::SoundSample^ sample;


    Filip Skakun

    • Marked as answer by Filip Skakun Tuesday, April 3, 2012 11:29 PM
    Tuesday, April 3, 2012 11:29 PM

All replies

  • Solved it (thanks to Jeremiah Morrill) - the problem is not with any barrier blocking the use of ref classes in basic classes. C4430 means that SoundSample is an unrecognized type, which was hidden by Intellisense - since that seemed to indicate that SoundSample is known. What needs to be added is a declaration of the SoundSample type and this all starts working fine.

    I just added

    namespace MyNamespace { ref class SoundSample; }

    before the SoundCallback class declaration and then SoundCallback class could declare:

    MyNamespace::SoundSample^ sample;


    Filip Skakun

    • Marked as answer by Filip Skakun Tuesday, April 3, 2012 11:29 PM
    Tuesday, April 3, 2012 11:29 PM
  • Thanks for sharing the solution.

    Best regards,
    Jesse


    Jesse Jiang [MSFT]
    MSDN Community Support | Feedback to us

    Wednesday, April 4, 2012 6:13 AM