开发者

c++ call delegate from unmanaged code in a different thread

[Apologies in advance. I've read several postings both here and codeproject.com on this topic, but I'm still missing something.]

I have a notification framework (analogous to Events) as part of a legacy system written in unmanaged C++. I also have a mixed-mode DLL with managed classes exposing legacy functionality to the managed world.

The CacheControlNotification class is a manage bridge class intended to translate the unamanged events to managed events. It contains an unmanaged NativeCcmBridge class which is registered in the legacy framework to receive the unmanaged messages. The NativeCcmBridge marshals the data to a managed type and passes it up to the CacheControlNotification where it dispatched to interested managed parties.

GetDelegateForFunctionPointer() is throwing NotSupportedException: Delegates cannot be marshaled from native code into a domain other than their home domain.

The callbacks occur in threads originating in the native code. The exception leads me to believe my solution is fundamentally flawed.

Any help is appreciated. Thanks.

Robert

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:
        NativeCc开发者_运维百科mBridge ( 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 );
        }
};
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜