将委托定义为函数指针

我正在使用一个调用非托管函数指针的委托。 这会导致垃圾收集器在使用之前收集它,如MSDN上的CallbackOnCollectedDelegate MDA页面中所述:CallbackOnCollectedDelegate MDA的MSDN页面 。

该决议声明我必须将适当的委托编组为非托管函数指针。 我最初的反应是使用:

[MarshalAs(UnmanagedType.FunctionPtr)] public delegate void EntityCallback([MarshalAs(UnmanagedType.SysInt)] IntPtr entity); 

但是,C#编译器不会让我编组委托,即使这是MSDN建议的解决方案。 此外,MSDN页面仅显示抛出问题的示例,但不是解决方案之一。

我怎么能将我的委托编组为一个非托管函数指针或阻止它被GCed?

编辑 :根据建议,我创建了回调的引用。 因此,我的代码从/更改为:

 // From: foo.SetCallback(new EntityCallback(bar)); // To: call = new EntityCallback(bar); // Referenced in class foo.SetCallback(call); 

现在这确实有效 – 但仅限于调试模式。 当我切换到Release时,它会在同一点崩溃。 这是为什么?

编辑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); } } 

你没有正确阅读。 你必须这样做:

…更改您的代码,以便在封送的非托管函数指针的生命周期内保持对托管端的该委托的引用。

换句话说,只需在类中存储对委托实例的引用,并确保类对象能够存活足够长的时间。 如果你真的需要,请使用静态。