使用P/Invoke时如何将Win32类型映射到C#类型?

Lou*_*hys 11 c# pinvoke winapi performancecounter

我试图做这样的事情在C#.我发现如何使用此链接中的 P/Invoke C#调用Win32方法.但是我在实现P/Invoke方面遇到了一些困难.

例如,我想访问的方法之一是PdhOpenQuery,签名:

PDH_STATUS PdhOpenQuery(
  __in   LPCTSTR szDataSource,
  __in   DWORD_PTR dwUserData,
  __out  PDH_HQUERY *phQuery
);
Run Code Online (Sandbox Code Playgroud)

我认为相应的C#声明应该是这样的

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

我的问题:

什么是LPCTSTR,以及它在C#中映射的数据类型是什么?
如何映射指针类型DWORD_PTR?pinvoke文章说DWORD映射到UInt32,但指针怎么样?
我认为PDH_STATUS和PDH_HQUERY是库的特定结构(我还不确定).我该如何映射这些?

什么是正确的方法声明,以及如何正确地调用它?

dan*_*n04 19

什么是LPCTSTR,以及它在C#中映射的数据类型是什么?

LPCTSTR是一个typedef 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);
Run Code Online (Sandbox Code Playgroud)