Как сопоставить типы Win32 с типами C # при использовании P / Invoke? - PullRequest
10 голосов
/ 30 августа 2010

Я пытаюсь сделать что-то вроде this в 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 являются специфической структурой для библиотеки (пока не уверен).как мне их сопоставить?

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

Ответы [ 3 ]

18 голосов
/ 30 августа 2010

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

LPCTSTR - это typedef для const TCHAR*.

TCHAR - это попытка абстрагироваться от того факта, что Windows API существует как в версиях "ANSI" (char в кодировке, зависящей от локали), так и в версиях "Юникод" (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);
0 голосов
/ 30 августа 2010

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

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

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

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

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

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

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

0 голосов
/ 30 августа 2010
[DllImport("Pdh.dll")]
    static extern Int32 PdhOpenQuery(string szDataSource, 
        IntPtr dwUserData, ref IntPtr phQuery);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...