非静态回调如何从本机代码中运行?

时间:2013-03-27 18:04:59

标签: c# c++ callback thunk

提出这个问题有点奇怪,因为我的代码似乎不应该起作用,但确实如此,虽然我不抱怨,但我想确认原因? LOL

简单地说,我有一个C ++本机DLL(根本没有CLR /托管支持)从C#代码中回拨。本机端存储stdcall回调函数,该函数由C#端提供。我一直认为回调METHOD(在C#中)必须是静态的,但是非静态和lambda表达式两种工作都很简单!? “this”指针是如何从本机代码编组的?我一直以为本机代码只存储非实例函数指针?

现在,我找到了一篇文章,其中一些人发出了IL代码,以便在本地和非静态托管回调之间“桥接”。我还注意到了这种折旧的方法:“Marshal.GetUnmanagedThunkForManagedMethodPtr()”。不再支持该方法,我假设它意味着它是内置的?

问题摘要:

  1. 现在通过发送IL代码将thunking本地构建到.NET中吗?如果是这样,那么在什么版本的.NET上本地支持它?

  2. Mono也支持隐式“thunking”吗?

  3. 当为托管回调发出IL时,会发生什么 thunk引用的实例被删除了吗?是否删除了IL,或 可能这会导致记忆“泄漏”吗?

  4. 感谢。

2 个答案:

答案 0 :(得分:2)

  

现在通过发送IL代码将thunking本地构建到.NET中吗?如果是这样,那么在什么版本的.NET上本地支持它?

没有涉及thunk的IL,它通过发出本机代码发生 - 一个重新排列参数以满足.NET的调用约定的蹦床,包括在关闭代理的情况下保存的this指针,然后执行对.NET方法本身的尾调用。

  

Mono是否支持隐式“thunking”?

这称为“反向调用/调用”,这样可以在Mono文档中轻松查找。

  

当为托管回调发出IL时,当thunk引用的实例被删除时会发生什么?

当委托被垃圾收集时,蹦床使用的内存也被释放。因此,只要本机代码具有指向蹦床的指针,您就需要保持委托存活。

答案 1 :(得分:1)

interop marshaller只是编组一名代表。委托可以是类委托(无this)或实例委托(具有this)。从C#的角度来看,它只是在调用一个委托。即,有效地使用与实例委托管理this相同的语义(例如,类实例的解耦)。

显然,还有更多内容与其他内容(例如钉扎等)有关 - 但它们通常与您提出的问题无关。