Как сопоставить типы Win32 с типами C # при использовании P / Invoke?

Я пытаюсь сделать что-то вроде этого в C #. Я узнал, как вызывать методы Win32 из C #, используя P / Invoke по этой ссылке . Однако я столкнулся с некоторыми трудностями при реализации P / Invoke.

Например, один из методов, к которым я хотел бы получить доступ, это PdhOpenQuery , подпись:

PDH_STATUS PdhOpenQuery(
  __in   LPCTSTR szDataSource,
  __in   DWORD_PTR dwUserData,
  __out  PDH_HQUERY *phQuery
);

Я считаю, что соответствующее объявление C # должно быть примерно таким

    [DllImport("Pdh.dll")]
    static extern PDH_STATUS PdhOpenQuery(LPCTSTR szDataSource, 
        DWORD_PTR dwUserData, out PDH_HQUERY *phQuery);

Мои вопросы:

Что такое LPCTSTR и с каким типом данных он сопоставляется в C #?
Как отобразить указатель типа DWORD_PTR? В статье о pinvoke говорится, что DWORD отображается на UInt32, но как насчет указателей?
Я думаю, что PDH_STATUS и PDH_HQUERY являются специфической структурой для библиотеки (я еще не уверен). как мне их сопоставить?

Что такое правильное объявление метода и как его правильно вызвать?

11
задан Louis Rhys 30 August 2010 в 07:57
поделиться

3 ответа

Что такое LPCTSTR и к какому типу данных это отображается в С#?

LPCTSTR — это определение типа для const TCHAR*.

TCHAR — это попытка абстрагироваться от того факта, что Windows API существует как в «ANSI» (строки char в кодировке, зависящей от локали), так и в «Unicode» (UTF-16). версии. Фактической функции PdhOpenQuery нет; есть функция PdhOpenQueryA, которая принимает строку ANSI, и функция PdhOpenQueryW, которая принимает строку UTF-16.

В C# используются строки UTF-16, поэтому вам следует предпочесть версию "W" этих функций. Используйте PdhOpenQueryW. Тогда первый параметр имеет тип C++ const wchar_t*.Тип C# — [MarshalAs(UnmanagedType.LPWStr)] string.

Как сопоставить указатель типа DWORD_PTR? В статье pinvoke говорится, что DWORD сопоставляется с UInt32, а как насчет указателей?

DWORD_PTR не является указателем. Это целое число без знака, достаточно большое, чтобы удерживать указатель. Эквивалентным типом C# является System.UIntPtr.

Я думаю, что PDH_STATUS и PDH_HQUERY конкретная структура в библиотеку (я пока не уверен). как мне их сопоставить?

PDH_STATUS выглядит как int.

PDH_HQUERY — это указатель на дескриптор (другой указатель), но вы можете просто притвориться, что это целое число, и использовать IntPtr.

Собрав все вместе, ваша декларация должна быть:

[DllImport("Pdh.dll")]
static extern int PdhOpenQueryW(
    [MarshalAs(UnmanagedType.LPWStr)] string szDataSource, 
    UIntPtr dwUserData,
    out IntPtr phQuery);
19
ответ дан 3 December 2019 в 06:19
поделиться

iirc LPCTSTR состоит из: LP == Длинный указатель // реликвия от 16-битного до 32-битного преобразования

C == Константа

TSTR == TStr // TString, что-то вроде заполнителя, который будет замещать разные типы строк в зависимости от различных Заголовки C и #define

что это значит для вас: это указатель на строку, для C# просто используйте строку, и все будет в порядке.

PDH_STATUS — это указатель на структуру DH_STATUS, поэтому вам потребуется определить соответствующую структуру C#.

Ознакомьтесь с P/Invoke.Net для некоторых примеров использования p/invoke для стандартных заголовков, структур и функций Windows. Веб-сайт довольно неуклюж, вам просто нужно продолжать нажимать и расширять элементы в левой колонке.

P/Invoke плохо документирован, но как только вы сопоставите структуру и внешний вызов функции, вы должны быть в деле.

0
ответ дан 3 December 2019 в 06:19
поделиться
[DllImport("Pdh.dll")]
    static extern Int32 PdhOpenQuery(string szDataSource, 
        IntPtr dwUserData, ref IntPtr phQuery);
0
ответ дан 3 December 2019 в 06:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: