Defining a delegate as a function pointer

不打扰是莪最后的温柔 提交于 2019-12-01 02:58:20

问题


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

回答1:


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.



来源:https://stackoverflow.com/questions/3691873/defining-a-delegate-as-a-function-pointer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!