Я использую делегат, который вызывает указатель неуправляемой функции.Это приводит к тому, что сборщик мусора собирает его перед его использованием, как описано на странице MDA CallbackOnCollectedDelegate на MSDN: Страница MSDN для MDB CallbackOnCollectedDelegate .
В разрешении указывается, что необходимо выполнитьсоответствующий делегат как указатель неуправляемой функции.Мой первоначальный рефлекс заключался в использовании:
[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);
}
}