我正在使用调用非托管函数指针的委托。这会导致垃圾收集器在使用之前对其进行收集,如 MSDN 上的 CallbackOnCollectedDelegate MDA 页面中所述:CallbackOnCollectedDelegate MDA 的 MSDN 页面 http://msdn.microsoft.com/en-us/library/43yky316.aspx.
该决议指出我必须将适当的委托封送为非托管函数指针。我最初的反应是使用:
[MarshalAs(UnmanagedType.FunctionPtr)]
public delegate void EntityCallback([MarshalAs(UnmanagedType.SysInt)] IntPtr entity);
但是,C# 编译器不会让我封送委托,即使这是 MSDN 建议的解决方案。此外,MSDN页面仅显示了引发问题的示例,但没有提供解决方案。
如何将我的委托编组为非托管函数指针或防止其被 GC 处理?
EDIT:按照建议,我创建了回调的引用。因此,我的代码从/更改为:
// From:
foo.SetCallback(new EntityCallback(bar));
// To:
call = new EntityCallback(bar); // Referenced in class
foo.SetCallback(call);
现在这确实有效 - 但仅限于调试模式。当我切换到发布时,它在同一点崩溃。这是为什么?
EDIT 2:更完整的代码片段:
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);
}
}