将代理定义为函数指针 [英] Defining a delegate as a function pointer
问题描述
我正在使用一个调用非托管函数指针的委托。这将导致垃圾收集器在使用之前收集它,如MSDN上的CallbackOnCollectedDelegate MDA页面所述: CallbackOnCollectedDelegate MDA的MSDN页面。
分辨率表明我必须将适当的委托作为非托管函数指针进行编组。我的初始反应是使用:
[MarshalAs(UnmanagedType.FunctionPtr)]
public delegate void EntityCallback([MarshalAs (UnmanagedType.SysInt)] IntPtr实体);
但是,C#编译器不会让我组织一个委托,即使这是建议的解决方案由MSDN。此外,MSDN页面仅显示一个被抛出的问题的示例,但不是其中一个解决方案。
如何将我的委托作为非托管函数指针进行编组或保留它是从GCed?
编辑:建议,我创建了回调的引用。因此,我的代码从/更改为:
// From:
foo.SetCallback(new EntityCallback(bar) );
// To:
call = new EntityCallback(bar); //在类
中引用参数foo.SetCallback(call);
现在这可以正常工作,但只能在调试模式下运行。当我切换到Release时,它会在同一时刻崩溃。为什么?
编辑2 :更完整的代码段:
public class Test
{
private EntityCallback Call;
private void Bar(System.IntPtr target)
{
...
}
public Entity Foo {get;组; }
public Test()
{
this.Foo = new Body.Sphere(){Visible = false}; //不相关
this.Foo.CollisionType = 3; //不相关
this.Call = new EntityCallback(this.Bar);
this.Foo.SetCallback(this.Call,EntityCallbackType.Collision);
}
}
你没有正确读取它。您必须这样做:
...更改您的代码,以便在受管理端保留一个引用
给代理
$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $
$ b换句话说,只是存储对代理的引用在你的课堂中,确保课程对象能够持续足够长时间。如果你真的要使用静态。
I am using a delegate which calls an unmanaged function pointer. This causes the Garbage Collector to collect it before it is used, as described in the CallbackOnCollectedDelegate MDA page on MSDN: MSDN page for CallbackOnCollectedDelegate MDA.
The resolution states that I have to marshal the appropriate delegate as an unmanaged function pointer. My initial reflex was to use:
[MarshalAs(UnmanagedType.FunctionPtr)] public delegate void EntityCallback([MarshalAs(UnmanagedType.SysInt)] IntPtr entity);
However, the C# compiler won't let me marshal a delegate, even if this is the suggested resolution by MSDN. Moreover, the MSDN page only shows an example of the problem being thrown, but not one of the resolution.
How could I marshal my delegate as an unmanaged function pointer or keep it from being GCed?
EDIT: As suggested, I created a reference of the callback. Therefore, my code changed from/to:
// From: foo.SetCallback(new EntityCallback(bar)); // To: call = new EntityCallback(bar); // Referenced in class foo.SetCallback(call);
Now this does work - but only in Debug mode. When I switch to Release, it crashes at the same point. Why is that?
EDIT 2: More complete code snippet:
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); } }
解决方案You didn't read it correctly. You must do this:
...change your code to keep a reference to that delegate on the managed side for the lifetime of the marshaled unmanaged function pointer.
In other words, just store a reference to the delegate instance in your class and make sure the class object survives long enough. Use a static if you really have to.
这篇关于将代理定义为函数指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!