C++/CLI Managed Function To Native Callback Function

23 篇文章 0 订阅

一. 关键内核

System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate

此函数实现了Delegate转化为Native Function

二. 具体步骤
1. 创造和Native Function 一致的Delegate
Native Function:

typedef bool (*ONSESSRELY)(HANDLE_CONN, HANDLE_SESSION, long); //long 为 32bit

Managed Delegate:

    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    public delegate bool ONSESSIONREPLY(IntPtr hConnect, IntPtr hSession, eAbossFn fnId);// eAbossFn 是 enum:int

注意调用方式必须和Native Function一致

  1. 将Managed Function 转化为 Delegate
ONSESSIONREPLY^ pFunc = gcnew ONSESSIONREPLY(this, &YourClass::MemberFunction);
ONSESSIONREPLY^ pFunc = gcnew ONSESSIONREPLY(YourClass::StatiMemberFunction);
  1. 将Delegate转化为Native Function
GCHandle gch = GCHandle::Alloc(pFunc);// System::Runtime::InteropServices::GCHandleType::Pinned);   
auto thunk = System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(pFunc);
::Native_RegisterService(hSess.ToInt32(), thunk.ToPointer());
//Free gch, after Native used thunk

4.注意事项
关于Delegate实例,必须在其被Native调用前不能被GC回收。
有2中方法。
a.保存在类的结构中
b.保存在GCHandle中
一旦被GC回收后,Native 如果调用 thunk 将会访问未知内容
所以,你可以自己存储在类结构中,或者存储在 GCHandle中。
这两种方法都需要自己维护Delegate的生存周期。
注意: Delegate 使用 GCHandle::Alloc来保存Delegate时,不需要,也无法设置为 Pinned
因为尽管GCHadle::Alloc保存Delegate后,因为没有Pinned,其真实地址会被GCmove,但是函数GetFunctionPointerForDelegate在转换Delegate到Native Function时,在GC外部创建了一个“native thunk” ,这个 “native thunk”才是native 访问的地址, 当然 native thunk 内部会接着访问 managed delegate。

Chris Brumme wrote:
Along the same lines, managed Delegates can be marshaled to unmanaged code, where they are exposed as unmanaged function pointers. Calls on those pointers will perform an unmanaged to managed transition; a change in calling convention; entry into the correct AppDomain; and any necessary argument marshaling. Clearly the unmanaged function pointer must refer to a fixed address. It would be a disaster if the GC were relocating that! This leads many applications to create a pinning handle for the delegate. This is completely unnecessary. The unmanaged function pointer actually refers to a native code stub that we dynamically generate to perform the transition & marshaling. This stub exists in fixed memory outside of the GC heap.

这里写链接内容

https://stackoverflow.com/questions/33393690/passing-a-c-sharp-callback-function-into-managed-and-unmanaged-c-libraries

https://stackoverflow.com/questions/28982669/does-gchandle-alloc-allocate-memory

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值