如何在 Native C++ 中使用 托管代码的函数 作为回调函数

  1. 我们通常使用Delegate 来包装托管代码的函数,这次也不例外。

  2.    IntPtr ip = Marshal::GetFunctionPointerForDelegate(fp);
  3.    ANSWERCB cb = static_cast<ANSWERCB>(ip.ToPointer());
  4.    Console::WriteLine("[managed] sending delegate as callback...");
MSDN 原文地址:
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

我自己写了一个简单的例子
  1. 头文件:
  2. //#include "interface.h"
  3. #include <string>
  4. #include<vcclr.h>
  5. #pragma once
  6. using namespace System;
  7. typedef int (__stdcall * CALLBACK_NATIVE)();
  8. public class NativeClass 
  9. {
  10. private
  11.     CALLBACK_NATIVE pFunc;
  12. public
  13.     void GetCallback(CALLBACK_NATIVE func); 
  14.     void UseCallback();
  15.     
  16. };
  17. public delegate int CALLBACK_MGD(void);
  18. public ref class ManagedClass
  19. {
  20. private:
  21.     NativeClass * pNativeClass;
  22.     
  23. public
  24.     ManagedClass();
  25.     //wants to be call in NativeClass
  26.     static int GenerateBitmap();
  27. };

CPP 文件:
  1. #include "stdafx.h"
  2. #include "CLI_Hello.h"
  3. #include <iostream>
  4. using namespace std;
  5. using namespace System::Runtime::InteropServices;
  6. ManagedClass::ManagedClass()
  7. {
  8.     this->pNativeClass = new NativeClass();
  9. }
  10. int ManagedClass::GenerateBitmap()
  11. {
  12.     Console::WriteLine("Managed Call Back Method Working!");
  13.     return 5;
  14. }
  15. void NativeClass::GetCallback(CALLBACK_NATIVE func)
  16. {
  17.     this->pFunc = func;
  18. }
  19. void NativeClass::UseCallback()
  20. {
  21.     cout<<"Use Managed Class Callback"<<endl;
  22.     this->pFunc();
  23. }
调用者,main 函数:
  1. int main(array<System::String ^> ^args)
  2. {
  3.     NativeClass nativeClass;
  4.     
  5.     //Step (1) Wrap Managed function to delegate.
  6.     CALLBACK_MGD^ callbackDelegate = gcnew CALLBACK_MGD(ManagedClass::GenerateBitmap);
  7.     //Step (2) Protect callbackDelegate not to be release by GC. 
  8.     GCHandle gch = GCHandle::Alloc(callbackDelegate);
  9.     //Step (3) Convert managed delegate to void * point by Marshal.
  10.     System::IntPtr ptr = Marshal::GetFunctionPointerForDelegate(callbackDelegate);
  11.     // Convert pointer to Native Callback type.
  12.     CALLBACK_NATIVE pCallback = static_cast<CALLBACK_NATIVE>(ptr.ToPointer());
  13.     
  14.     nativeClass.GetCallback(pCallback);
  15.     // Run that Callback
  16.     nativeClass.UseCallback();
  17.     //Step (4) Release ...
  18.     gch.Free();
  19.     Console::WriteLine("Finished");
  20.     Console::Read();
  21.     return 0;
  22. }
如果希望callback函数是一个成员函数,而不是static静态函数我们可以这样做:
  1. public delegate int CALLBACK_MGD(void);
  2. public ref class ManagedClass
  3. {
  4. private:
  5.     NativeClass * pNativeClass;
  6.     
  7. public
  8.     ManagedClass();
  9.     //wants to be call in NativeClass,This is not static but member function!!!
  10.     int  GenerateBitmap();
  11. };
调用:
  1. //First new instance of this managed Class.
  2. ManagedClass^ mc = gcnew ManagedClass();
  3.     
  4. //Then Wrap Managed function to delegate.
  5. CALLBACK_MGD^ callbackDelegate = gcnew    CALLBACK_MGD(mc,&ManagedClass::GenerateBitmap);
  6. //delegate 有自己的构造函数,他允许代理成员函数,只是需要对象地址。


我觉得应该挺清楚了,弄了好几个小时,CLI 真是门道多阿,不到万不得已真不想用它。
现在应该考虑 不同托管Callback 返回的数据 interop 给本地代码是用的问题了。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值