c++从不同线程中的非托管代码调用委托
[提前致歉。我已经阅读了此处和 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 );
}
};
[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:
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 );
}
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论