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

时间:2010-08-30 06:08:22

标签: c# winapi pinvoke performancecounter

我正在尝试在C#中执行this之类的操作。我发现了如何使用P / Invoke from this link从C#调用Win32方法。但是我在实现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 个答案:

答案 0 :(得分:18)

  

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

LPCTSTRconst TCHAR*的typedef。

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);

答案 1 :(得分:0)

[DllImport("Pdh.dll")]
    static extern Int32 PdhOpenQuery(string szDataSource, 
        IntPtr dwUserData, ref IntPtr phQuery);

答案 2 :(得分:0)

iirc LPCTSTR分解为: LP ==长指针//从16位到32位通信的遗物

C ==常数

TSTR == TStr // TString,一种占位符,可以替换不同类型的字符串,具体取决于各种C头和#defines

对你来说意味着什么:它是一个指向字符串的指针,对于C#只是使用字符串,你就没事了。

PDH_STATUS是指向DH_STATUS结构的指针,因此您需要定义要匹配的C#结构。

查看P/Invoke.Net以了解在标准Windows标头,结构和函数上使用p / invoke的一些示例。该网站有点笨拙,你只需要点击并展开左栏中的项目。

P / Invoke没有很好的文档记录,但是一旦你映射了结构和extern函数调用,你就应该开展业务了。