- 我们通常使用Delegate 来包装托管代码的函数,这次也不例外。
- IntPtr ip = Marshal::GetFunctionPointerForDelegate(fp);
- ANSWERCB cb = static_cast<ANSWERCB>(ip.ToPointer());
- Console::WriteLine("[managed] sending delegate as callback...");
http://msdn.microsoft.com/zh-cn/magazine/cc164193.aspx
http://msdn.microsoft.com/zh-cn/library/ms177552.aspx
http://msdn.microsoft.com/zh-cn/library/367eeye0.aspx
我自己写了一个简单的例子
- 头文件:
- //#include "interface.h"
- #include <string>
- #include<vcclr.h>
- #pragma once
- using namespace System;
- typedef int (__stdcall * CALLBACK_NATIVE)();
- public class NativeClass
- {
- private:
- CALLBACK_NATIVE pFunc;
- public:
- void GetCallback(CALLBACK_NATIVE func);
- void UseCallback();
- };
- public delegate int CALLBACK_MGD(void);
- public ref class ManagedClass
- {
- private:
- NativeClass * pNativeClass;
- public:
- ManagedClass();
- //wants to be call in NativeClass
- static int GenerateBitmap();
- };
CPP 文件:
- #include "stdafx.h"
- #include "CLI_Hello.h"
- #include <iostream>
- using namespace std;
- using namespace System::Runtime::InteropServices;
- ManagedClass::ManagedClass()
- {
- this->pNativeClass = new NativeClass();
- }
- int ManagedClass::GenerateBitmap()
- {
- Console::WriteLine("Managed Call Back Method Working!");
- return 5;
- }
- void NativeClass::GetCallback(CALLBACK_NATIVE func)
- {
- this->pFunc = func;
- }
- void NativeClass::UseCallback()
- {
- cout<<"Use Managed Class Callback"<<endl;
- this->pFunc();
- }
- int main(array<System::String ^> ^args)
- {
- NativeClass nativeClass;
- //Step (1) Wrap Managed function to delegate.
- CALLBACK_MGD^ callbackDelegate = gcnew CALLBACK_MGD(ManagedClass::GenerateBitmap);
- //Step (2) Protect callbackDelegate not to be release by GC.
- GCHandle gch = GCHandle::Alloc(callbackDelegate);
- //Step (3) Convert managed delegate to void * point by Marshal.
- System::IntPtr ptr = Marshal::GetFunctionPointerForDelegate(callbackDelegate);
- // Convert pointer to Native Callback type.
- CALLBACK_NATIVE pCallback = static_cast<CALLBACK_NATIVE>(ptr.ToPointer());
- nativeClass.GetCallback(pCallback);
- // Run that Callback
- nativeClass.UseCallback();
- //Step (4) Release ...
- gch.Free();
- Console::WriteLine("Finished");
- Console::Read();
- return 0;
- }
如果希望callback函数是一个成员函数,而不是static静态函数我们可以这样做:
- public delegate int CALLBACK_MGD(void);
- public ref class ManagedClass
- {
- private:
- NativeClass * pNativeClass;
- public:
- ManagedClass();
- //wants to be call in NativeClass,This is not static but member function!!!
- int GenerateBitmap();
- };
- //First new instance of this managed Class.
- ManagedClass^ mc = gcnew ManagedClass();
- //Then Wrap Managed function to delegate.
- CALLBACK_MGD^ callbackDelegate = gcnew CALLBACK_MGD(mc,&ManagedClass::GenerateBitmap);
- //delegate 有自己的构造函数,他允许代理成员函数,只是需要对象地址。
现在应该考虑 不同托管Callback 返回的数据 interop 给本地代码是用的问题了。