定义一个委托作为函数指针 [英] Defining a delegate as a function pointer

查看:351
本文介绍了定义一个委托作为函数指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用它调用非托管函数指针的委托。这将导致垃圾收集器收集它,使用它之前,作为MSDN的CallbackOnCollectedDelegate MDA页面描述:的为CallbackOnCollectedDelegate MDA 的MSDN页面。



这是我必须元帅适当的委托作为非托管函数指针的解决状态。我最初的反射是使用:

  [的MarshalAs(UnmanagedType.FunctionPtr)
公众委托无效EntityCallback([的MarshalAs (UnmanagedType.SysInt)] IntPtr的实体);



不过,C#编译器不会让我元帅代表,即使这是建议的解决方案通过MSDN。此外,MSDN页面只显示了问题的一个例子被抛出,但不是决议之一。



我怎么能元帅我的委托作为非托管函数指针或保留它被GCed



修改:作为建议,我创建了回调的参考。因此,我的代码改为从/到:

  //来源:
foo.SetCallback(新EntityCallback(巴) );

//要:
调用=新EntityCallback(巴); //引用类
foo.SetCallback(电话);

现在这样做的工作 - 但只有在调试模式下。当我切换到发布,它崩溃在同一地点。 ?这是为什么



编辑2 :更完整的代码片段:

 公共类测试
{
私人EntityCallback呼叫;

私人无效栏(System.IntPtr目标)
{

}

公共实体的Foo {搞定;组; }

公开测试()
{
this.Foo =新Body.Sphere(){可见= FALSE}; //无关
this.Foo.CollisionType = 3; //无关

this.Call =新EntityCallback(this.Bar);

this.Foo.SetCallback(this.Call,EntityCallbackType.Collision);
}
}


解决方案

您没有正确读取它。你必须这样做:




...更改您的代码,以保持一个参考
到委托的管理方
为封
非托管函数指针的寿命。




在换句话说,只储存到委托的引用比如在你的类,并确保类对象存活足够长的时间。使用静态,如果你真的不得不这样做。


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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆