Почему я не могу передать реализацию SafeHandle определенным функциям pinvoke - PullRequest
0 голосов
/ 05 января 2019

Я пытаюсь заменить любые дескрипторы, которые я использую, своим кодом pinvoke на реализацию SafeHandles

В частности, я создал реализацию SafeThreadHandle, подобную этой

internal class SafeThreadHandle : SafeHandleZeroOrMinusOneIsInvalid
{
    internal SafeThreadHandle() : base(true) {}

    protected override bool ReleaseHandle()
    {
        return CloseHandle(handle);
    }
}

Это прекрасно работает в большинстве случаев, например

[DllImport("kernel32.dll")]
internal static extern int ResumeThread(SafeThreadHandle threadHandle);

Когда я пытаюсь использовать SafeThreadHandle в качестве параметра для следующих двух функций pinvoke, функция завершается ошибкой и устанавливает ошибку Windows 998, для которой состояния msdn следующие:

ERROR_NOACCESS 998 (0x3E6) Неверный доступ к ячейке памяти.

[DllImport("kernel32.dll")]
internal static extern bool GetThreadContext(SafeThreadHandle threadHandle, ref Context64 context);


[DllImport("kernel32.dll")]
internal static extern bool SetThreadContext(SafeThreadHandle threadHandle, ref Context64 context);

Странно то, что если я заменю SafeThreadHandle на IntPtr (параметр и аргумент) для дескриптора потока, получаемого через threadHandle.GetDangerousHandle(), функции завершаются успешно и работают так, как они должны.

Итак, я думаю, что мой вопрос заключается в том, почему я не могу использовать мою SafeThreadHandle реализацию SafeHandle в качестве параметра для двух вышеуказанных функций, но я могу использовать его для других функций, таких как ResumeThread

1 Ответ

0 голосов
/ 06 января 2019

Так что после большого тестирования и помощи от Саймона мне удалось вывести проблему до ссылки на структуры контекста в функции pinvoke.

По какой-то причине я не смог использовать свой SafeThreadHandle в качестве параметра, если использовал ссылку.

Таким образом, решение было сделать следующее изменение

[DllImport("kernel32.dll")]
internal static extern bool GetThreadContext(SafeThreadHandle threadHandle, IntPtr context);

А затем вывести структуру из указателя.

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