Умирает объект созданный при помощи EasyHook

159
18 ноября 2020, 19:30

Я немного не до понимаю время жизни меж-доменных объектов, они же MarshalByRefObject, но вот я поставил хук на IDirect3DDevice9::EndScene, далее происходит какое-то время работы объекта, но дальше, он умирает.

Сообщения от рендерера:

Server: Ping response time: 6
Server: Ping response time: 0
Hook installed
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 1
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 1
EndScene hook called, Device is: 45792640
Server: Ping response time: 1
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 1
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 10
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 1
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
Server: Ping response time: 0
EndScene hook called, Device is: 45792640
ERROR: Renderer is destroyed!!!
Server: Ping response time: 0
ERROR: Renderer is destroyed!!!
Server: Ping response time: 0

Почему так происходит?

Код класса рендерера:


public class Renderer : MarshalByRefObject, IDisposable
{
    private readonly List<IntPtr> _vTable = new List<IntPtr>();
    private readonly OverlayManagerInterface _managerInterface;
    private readonly LocalHook _deviceResetHook;
    private readonly LocalHook _endSceneHook;
    [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
    private delegate int EndSceneDelegate(IntPtr devicePtr);
    public Renderer(OverlayManagerInterface managerInterface)
    {
        _managerInterface = managerInterface;
        using (Direct3D d3D = new Direct3D())
        {
            using (Form renderForm = new Form())
            {
                using (Device deviceGlobal = new Device(d3D, 0, DeviceType.NullReference, IntPtr.Zero,
                    CreateFlags.HardwareVertexProcessing,
                    new PresentParameters
                        {BackBufferWidth = 1, BackBufferHeight = 1, DeviceWindowHandle = renderForm.Handle}))
                {
                    _vTable.AddRange(GetVTblAddresses(deviceGlobal.NativePointer,
                        Enum.GetValues(typeof(D3D9Indexes.Direct3DDevice9FunctionOrdinals)).Length));
                }
            }
        }
        _endSceneHook = LocalHook.Create(_vTable[(int) D3D9Indexes.Direct3DDevice9FunctionOrdinals.EndScene],
            new EndSceneDelegate(EndScene), this);
        _endSceneHook.ThreadACL.SetExclusiveACL(new int[1]);
        _managerInterface.Ping(DateTime.Now);
        _managerInterface.OnManagerMessage("Hook installed");
    }
    public List<IOverlay> Overlays { get; } = new List<IOverlay>();
    public void Dispose()
    {
        ReleaseUnmanagedResources();
        GC.SuppressFinalize(this);
    }
    private static IEnumerable<IntPtr> GetVTblAddresses(IntPtr pointer, int numberOfMethods)
    {
        List<IntPtr> vTblAddresses = new List<IntPtr>();
        IntPtr vTable = Marshal.ReadIntPtr(pointer);
        for (int i = 0; i < numberOfMethods; i++) vTblAddresses.Add(Marshal.ReadIntPtr(vTable, i * IntPtr.Size));
        return vTblAddresses.ToArray();
    }
    private void ReleaseUnmanagedResources()
    {
        foreach (IOverlay overlay in Overlays) overlay.Dispose();
        LocalHook.Release();
        Thread.Sleep(2000);
        _managerInterface.OnManagerMessage("ERROR: Renderer is destroyed!!!");
        _managerInterface.Ping(DateTime.Now);
    }
    private int EndScene(IntPtr devicePtr)
    {
        Device device = new Device(devicePtr);
        _managerInterface.Ping(DateTime.Now);
        _managerInterface.OnManagerMessage("EndScene hook called, Device is: {0}", devicePtr);
        device.EndScene();
        return Result.Ok.Code;
    }
    private int DeviceReset(IntPtr devicePtr, PresentParameters[] presentParameters)
    {
        Device device = new Device(devicePtr);
        _managerInterface.Ping(DateTime.Now);
        _managerInterface.OnManagerMessage("DeviceReset hook called, Device is: {0}", devicePtr);
        device.Reset(presentParameters);
        return Result.Ok.Code;
    }
    ~Renderer()
    {
        ReleaseUnmanagedResources();
        _managerInterface.OnManagerMessage("ERROR: Renderer is destroyed!!!");
        _managerInterface.Ping(DateTime.Now);
    }
}

Как сделать так, что бы объект не умер?

READ ALSO
Получить AssemblyVersion из Assembly

Получить AssemblyVersion из Assembly

Можно ли получить AssemblyVersion из Assembly без загрузки ее в процесс(Из файла)?

141
Как реализовать запрос c Row_Number в MySQL?

Как реализовать запрос c Row_Number в MySQL?

Как реализовать ROW_NUMBER() OVER ( PARTITION BY row1, row2 ORDER BY row3) с двумя поля в PARTITION BY, как пример:

107
Не меняется кодировка(Collation) в столбце MySQL

Не меняется кодировка(Collation) в столбце MySQL

пытаюсь сделать столбец регистрозависимым путем смены Collation на utf8_binНо после выполнения скрипта ничего не меняется и столбец остается table default

149
Помогите с VBA в Access

Помогите с VBA в Access

Нужно чтобы при нажатии на кнопку из таблицы "товар" автоматически вычиталось количество товаров берущееся из таблицы "чек" при добавлении...

105