gpt4 book ai didi

c# - 将委托(delegate)定义为函数指针

转载 作者:太空狗 更新时间:2023-10-29 22:34:48 24 4
gpt4 key购买 nike

我正在使用调用非托管函数指针的委托(delegate)。这会导致垃圾收集器在使用它之前对其进行收集,如 MSDN 上的 CallbackOnCollectedDelegate MDA 页面中所述:MSDN page for CallbackOnCollectedDelegate MDA .

决议规定我必须将适当的委托(delegate)编码为非托管函数指针。我最初的 react 是使用:

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

但是,C# 编译器不允许我编码(marshal)委托(delegate),即使这是 MSDN 建议的解决方案。此外,MSDN 页面仅显示了抛出问题的示例,而没有显示任何解决方案。

如何将我的委托(delegate)编码为非托管函数指针或防止它被 GC 处理?

编辑:按照建议,我创建了回调的引用。因此,我的代码更改为:

// From:
foo.SetCallback(new EntityCallback(bar));

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

现在这确实有效 - 但仅限于 Debug模式。当我切换到 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);
}
}

最佳答案

你没看对。你必须这样做:

...change your code to keep a reference to that delegate on the managed side for the lifetime of the marshaled unmanaged function pointer.

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

关于c# - 将委托(delegate)定义为函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3691873/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com