【发布时间】:2011-04-11 03:36:00
【问题描述】:
我正在使用一个调用非托管函数指针的委托。这会导致垃圾收集器在使用之前对其进行收集,如 MSDN 上的 CallbackOnCollectedDelegate MDA 页面中所述:MSDN page for CallbackOnCollectedDelegate MDA。
决议规定我必须将适当的委托编组为非托管函数指针。我最初的反应是使用:
[MarshalAs(UnmanagedType.FunctionPtr)]
public delegate void EntityCallback([MarshalAs(UnmanagedType.SysInt)] IntPtr entity);
但是,C# 编译器不允许我编组委托,即使这是 MSDN 建议的解决方案。此外,MSDN 页面仅显示了引发问题的示例,但没有显示解决方案之一。
如何将我的委托编组为非托管函数指针或防止其被 GC?
编辑:按照建议,我创建了回调的引用。因此,我的代码从/更改为:
// From:
foo.SetCallback(new EntityCallback(bar));
// To:
call = new EntityCallback(bar); // Referenced in class
foo.SetCallback(call);
现在这确实有效 - 但仅限于调试模式。当我切换到 Release 时,它在同一点崩溃。这是为什么呢?
编辑2:更完整的代码sn-p:
public class Test
{
private EntityCallback Call;
private void Bar(System.IntPtr target)
{
...
}
public Entity Foo { get; set; }
public Test()
{
this.Foo = new Body.Sphere() { Visible = false }; // Irrelevant
this.Foo.CollisionType = 3; // Irrelevant
this.Call = new EntityCallback(this.Bar);
this.Foo.SetCallback(this.Call, EntityCallbackType.Collision);
}
}
【问题讨论】:
标签: c# delegates unmanaged function-pointers