专栏首页逍遥剑客的游戏开发把C++/CLI委托传入本地代码

把C++/CLI委托传入本地代码

参考: 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的转换一样, 需要注意保证内存指针不会被托管机制移动/回收.

  1. // DelegateCallback.cpp : main project file.
  2. #include "stdafx.h"
  3. #include <assert.h>
  4. #pragma unmanaged
  5. typedef void (__stdcall* EventCallback)(int);  
  6. class Native  
  7. {  
  8. public:  
  9. /// 注册回调函数
  10. static void RegisterCallback(EventCallback callback)  
  11.     {  
  12.         assert(0 != callback);  
  13.         ms_callback = callback;   
  14.     }  
  15. /// 调用注册的回调函数
  16. static void Invoke(int i)  
  17.     {  
  18.         assert(0 != ms_callback);  
  19.         ms_callback(i);  
  20.     };  
  21. private:  
  22. static EventCallback ms_callback;  
  23. };  
  24. EventCallback Native::ms_callback = 0;  
  25. #pragma managed
  26. using namespace System;  
  27. using namespace System::Runtime::InteropServices;  
  28. public delegate void EventDelegate(int i);  
  29. ref class NativeInterface  
  30. {  
  31. public:  
  32.     NativeInterface()  
  33.     {  
  34. // 从成员函数创建一个委托
  35. this->nativeCallback = gcnew EventDelegate(this, &NativeInterface::Callback);  
  36. // 保证委托不会被内存移动和垃圾回收掉
  37. this->delegateHandle = GCHandle::Alloc(this->nativeCallback);  
  38. // 转换为函数指针注册
  39.         IntPtr ptr = Marshal::GetFunctionPointerForDelegate(this->nativeCallback);  
  40.         Native::RegisterCallback( static_cast<EventCallback>(ptr.ToPointer()) );  
  41.     }  
  42.     ~NativeInterface()  
  43.     {  
  44. // 释放委托句柄
  45. if (this->delegateHandle.IsAllocated)  
  46. this->delegateHandle.Free();  
  47.     }  
  48. private:  
  49. void Callback(int i)  
  50.     {  
  51.         Console::WriteLine("托管命令行输出: {0}", i);  
  52.     }  
  53. private:  
  54.     GCHandle delegateHandle;  
  55.     EventDelegate^ nativeCallback;  
  56. };  
  57. //------------------------------------------------------------------------------
  58. int main(array<System::String^>^ args)  
  59. {  
  60.     NativeInterface^ ni = gcnew NativeInterface();  
  61. // 这个可以在native c++中调用
  62.     Native::Invoke(12345);  
  63. delete ni;  
  64.     ni = nullptr;  
  65. return 0;  
  66. }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 俄罗斯方块积木表示

    逍遥剑客
  • GDC2015: Networking for Physics Programmers

    逍遥剑客
  • MD2关键帧动画

    逍遥剑客
  • WordPress秒变谷歌AMP加速移动页面并自动推送

    沈唁
  • 专访FPGA 2017最佳论文得主深鉴科技: 深度学习的最大瓶颈是带宽问题而非计算

    AI科技评论按:近日,深鉴科技的 ESE 语音识别引擎的论文在 FPGA 2017 获得了唯一的最佳论文 ESE: Efficient Speech Recog...

    AI科技评论
  • 测试TCP 和 UDP 端口的方法

    p.p1 { margin: 0; font: 11px Menlo; color: rgba(0, 0, 0, 1); background-color: r...

    xuyaowen
  • 云计算市场即将获得更多竞争力

    如今,少数几家行业巨头在公共云市场近乎垄断的趋势似乎是不可逆转的,但强大的经济和技术力量正在引导人们走向一个不再围绕数据中心巩固市场的互联网。相反,人们所依赖的...

    静一
  • Windows核心编程:第14章 探索虚拟内存

    https://github.com/gongluck/Windows-Core-Program.git

    gongluck
  • 关于CentOS中tomcat的8005端口启动不起来的解决办法

    今早帮朋友在CentOS环境中配置tomcat服务器,结果tomcat的8005端口半天都起不来(tomcat的关闭端口),这个端口起不来就无法访问tomcat...

    端碗吹水
  • 大数据基础系列之kafka知识点和优点

    一,流式平台介绍 1,一般来说一个通用的流平台必须具备以下三个重要的能力: 1),能够允许你订阅和发布流式消息。在这方面,它类似于消息队列或企业消息系统。 2)...

    Spark学习技巧

扫码关注云+社区

领取腾讯云代金券