【问题标题】:How do non-static callbacks work from native code?非静态回调如何从本机代码工作?
【发布时间】:2013-03-17 23:11:30
【问题描述】:

问这个问题有点奇怪,因为我的代码似乎不应该工作,但它确实有效,虽然我没有抱怨,但我想确认为什么?哈哈

简单地说,我有一个 C++ 本机 DLL(根本没有 CLR/托管支持),它接受 C# 代码的回调。 native 端存储一个 stdcall 回调函数,由 C# 端提供。我一直认为回调方法(在 C# 中)必须是静态的,但非静态和 lambda 表达式都可以正常工作!?如何从本机代码封送“this”指针?一直以为原生代码只存储非实例函数指针?

现在,我确实找到了一篇文章,其中有人发出 IL 代码来“桥接”本机和非静态托管回调。我还注意到了这种贬值的方法:“Marshal.GetUnmanagedThunkForManagedMethodPtr()”。该方法不再受支持,我假设它是内置的?

问题总结:

  1. 现在是否通过发出 IL 代码将 thunking 内置到 .NET 中?如果是这样,在哪个版本的 .NET 中本机支持此功能?

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

  3. 当为托管回调发出 IL 时,当 thunk 引用的实例被删除了吗?是否删除了 IL,或者 可以这么说,这会导致内存“泄漏”吗?

谢谢。

【问题讨论】:

    标签: c# c++ callback thunk


    【解决方案1】:

    互操作编组器只是编组一个委托。委托可以是类委托(没有this)或实例委托(有this)。从 C# 的角度来看,它只是调用一个委托。即有效地使用了用于通过实例委托管理 this 的相同语义(例如,类实例的解耦)。

    很明显,还有更多关于其他事情的秘密(如钉住等)——但它们通常与您所询问的内容无关。

    【讨论】:

    • 我确实明白了这一点,但很高兴为其他人明确说明这一点,因为我很难找到关于它的可靠信息。 ;)
    【解决方案2】:

    thunking 现在是通过发出 IL 代码在 .NET 中内置的吗?如果是这样,它是在哪个版本的 .NET 中获得本机支持的?

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

    Mono 也支持隐式“thunking”吗?

    这称为“反向 p/invoke”,应该可以在 Mono 文档中轻松查找。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-09
      • 2011-11-06
      • 2012-03-06
      • 1970-01-01
      • 2016-08-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多