Заставить G C переместить объект в кучу - PullRequest
1 голос
/ 04 марта 2020

У меня есть класс, который содержит несколько делегатов, давайте назовем его EventContainer. Этот класс передается в собственную C ++ dll, где делегаты регистрируются как обратные вызовы для различных событий.

public class EventContainer
{
    public readonly SomeDelegate OnEvent1;
    // ...
}

Другой класс переносит эти делегаты в соответствующие C# события.

public class EventWrapper : IDisposable
{
    public event EventHandler Event1;

    private GCHandle _gcHandle;

    public EventWrapper()
    {
        var container = new EventContainer(OnEvent1)
        _gcHandle = GCHandle.Alloc(container);  // gets freed in Dispose
        UnmanagedApi.RegisterEvents(container); // register the delegates (also unregistered in Dispose)
    }

    private void OnEvent1()
    {
        Event1?.Invoke(this, EventArgs.Empty);
    }

    //...
}

Контейнер должен быть закреплен, потому что управление памятью. net иногда перемещает объекты в куче, и указатели на функции на стороне C ++ могут зависнуть, если это произойдет. Поэтому я хочу проверить, правильно ли прикреплен (и освобожден) контейнер (или, точнее, делегаты внутри него). Тестирование выпущено часть проста, но тестирование правильно закреплено часть сложно.

Мне бы пришлось заставить G C (или того, кто отвечает за сжатие кучи) переместить контейнер в кучу, чтобы делегаты получили новый адрес памяти. Если контейнер закреплен, его нельзя перемещать, и поэтому вызовы событий на стороне C ++ будут работать. Однако, если контейнер не был закреплен, указатели функций на стороне C ++ будут зависать, и их вызов после перемещения контейнера вызовет AccessViolationException (что-то в этом духе).

Для проверки это, я должен заставить переместить контейнера в кучу. Это возможно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...