[Извиняюсь заранее. Я прочитал несколько сообщений здесь и на 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 );
}
};