c ++ вызов делегата из неуправляемого кода в другом потоке - PullRequest
1 голос
/ 05 января 2011

[Извиняюсь заранее. Я прочитал несколько сообщений здесь и на codeproject.com на эту тему, но я все еще что-то упускаю.]

У меня есть структура уведомлений (аналог событий) как часть устаревшей системы, написанной на неуправляемом C ++. У меня также есть DLL-библиотека смешанного режима с управляемыми классами, предоставляющая унаследованную функциональность управляемому миру.

Класс CacheControlNotification - это класс управляющего моста, предназначенный для преобразования неуправляемых событий в управляемые события. Он содержит неуправляемый класс NativeCcmBridge, который зарегистрирован в устаревшей платформе для получения неуправляемых сообщений. NativeCcmBridge направляет данные в управляемый тип и передает их в CacheControlNotification, где они отправляются заинтересованным управляемым сторонам.

GetDelegateForFunctionPointer () создает исключение NotSupportedException: делегаты не могут быть перенесены из собственного кода в домен, отличный от их домашнего домена.

Обратные вызовы происходят в потоках, происходящих из собственного кода. Исключение заставляет меня полагать, что мое решение в корне неверно.

Любая помощь приветствуется. Спасибо.

Роберт

public delegate void OnNotifyHandler ( ManagedCallbackMessage^ );

//
// Native class to marshal callback to managed code.   Callbacks
// in the native world are registered via an "ANativeHandler" type.
//
class NativeCcmBridge : public ANativeHandler
{
    private:
        //
        // Pointer to the managed delegate
        //
        IntPtr m_callbackPtr;


    public:
        NativeCcmBridge ( OnNotifyHandler^ callback )
        {
            m_callbackPtr = Marshal::GetFunctionPointerForDelegate(callback);
        }

        //
        // Provide implementation for pure virtual native handler
        //
        virtual void OnNotify (NativeCallbackMsg& nativeCallbackMsg)
        {
            // Convert the native message to a managed message
            ManagedCallbackMessage^ msg = new ManagedCallbackMessage( nativeCallbackMsg );

            // Now push the managed message via the delegate
            // throws NotSupportedException:  Delegates cannot be marshaled from native code into a domain other than their home domain.
            OnNotifyHandler^ callback = (OnNotifyHandler^)Marshal::GetDelegateForFunctionPointer(m_callbackPtr, OnNotifyHandler::typeid);
            callback( msg );
        }

};

//
// Managed Class to receive marshalled messages and 
// reissue in managed world.
//
public ref class CacheControlNotification
{
    public:
        CacheControlNotification()
        {
            m_callback = (OnNotifyHandler^) Delegate::CreateDelegate( OnNotifyHandler::typeid, this, "RaiseNotification" );
            m_bridge = new NativeCcmBridge( m_callback );

            // Register m_bridge the native mechanism
        }

        virtual ~CacheControlNotification () { this->!CacheControlNotification(); }
        !CacheControlNotification ()
        {
            delete m_bridge;
            m_bridge = nullptr;
        }

        event OnNotifyHandler^ OnNotify;

    protected:
        NativeCcmBridge* m_bridge;
        pin_ptr<OnNotifyHandler^> m_callback;

        void RaiseNotification ( CacheControlMessage^ msg )
        {
            OnNotify( msg );
        }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...