參考: http://resnikb.wordpress.com/2009/05/18/passing-ccli-delegate-to-native-code/
C++/CLI可以直接執行C++, 這個沒有問題, 那麼反過來呢?
比如底層C++進行一項任務, 完成了需要通知上層的C++/CLI, 總不能在上面不停地查詢吧?
通常這是通過回調來實現的, 說漂亮點就是觀察者模式, 說成.net的就是委託.
而委託, 本質是就是函數指標. 以前也提到過C++委託的實現.
.net提供了一個方法把委託轉換成函數指標: Marshal::GetFunctionPointerForDelegate
跟String的轉換一樣, 需要注意保證記憶體指標不會被託管機制移動/回收.
// DelegateCallback.cpp : main project file.</p><p>#include "stdafx.h"<br />#include <assert.h></p><p>#pragma unmanaged<br />typedef void (__stdcall* EventCallback)(int);<br />class Native<br />{<br />public:<br />/// 註冊回呼函數<br />static void RegisterCallback(EventCallback callback)<br />{<br />assert(0 != callback);<br />ms_callback = callback;<br />}<br />/// 調用註冊的回呼函數<br />static void Invoke(int i)<br />{<br />assert(0 != ms_callback);<br />ms_callback(i);<br />};</p><p>private:<br />static EventCallback ms_callback;<br />};<br />EventCallback Native::ms_callback = 0;<br />#pragma managed</p><p>using namespace System;<br />using namespace System::Runtime::InteropServices;</p><p>public delegate void EventDelegate(int i);</p><p>ref class NativeInterface<br />{<br />public:<br />NativeInterface()<br />{<br />// 從成員函數建立一個委託<br />this->nativeCallback = gcnew EventDelegate(this, &NativeInterface::Callback);</p><p>// 保證委託不會被記憶體移動和記憶體回收掉<br />this->delegateHandle = GCHandle::Alloc(this->nativeCallback);</p><p>// 轉換為函數指標註冊<br />IntPtr ptr = Marshal::GetFunctionPointerForDelegate(this->nativeCallback);<br />Native::RegisterCallback( static_cast<EventCallback>(ptr.ToPointer()) );<br />}</p><p>~NativeInterface()<br />{<br />// 釋放委託控制代碼<br />if (this->delegateHandle.IsAllocated)<br />this->delegateHandle.Free();<br />}</p><p>private:<br />void Callback(int i)<br />{<br />Console::WriteLine("託管命令列輸出: {0}", i);<br />}<br />private:<br />GCHandle delegateHandle;<br />EventDelegate^ nativeCallback;<br />};</p><p>//------------------------------------------------------------------------------<br />int main(array<System::String^>^ args)<br />{<br />NativeInterface^ ni = gcnew NativeInterface();</p><p>// 這個可以在native c++中調用<br />Native::Invoke(12345);</p><p>delete ni;<br />ni = nullptr;</p><p> return 0;<br />}<br />