I am trying to do something like this in C#. I found out how to call Win32 methods from C# using P/Invoke from this link. However I met some difficulties in implementing P/Invoke.
For example, one of the methods that I would like to access is PdhOpenQuery, signature:
PDH_STATUS PdhOpenQuery(
  __in   LPCTSTR szDataSource,
  __in   DWORD_PTR dwUserData,
  __out  PDH_HQUERY *phQuery
);
I figure the corresponding C# declaration should be something like this
    [DllImport("Pdh.dll")]
    static extern PDH_STATUS PdhOpenQuery(LPCTSTR szDataSource, 
        DWORD_PTR dwUserData, out PDH_HQUERY *phQuery);
My questions:
What is LPCTSTR, and to what data type does it map in C#?
How to map a pointer type DWORD_PTR? The pinvoke article says DWORD maps to UInt32, but how about pointers?
I think PDH_STATUS and PDH_HQUERY are specific struct to the library (I'm not sure yet). how do I map these?
What is the correct method declaration, and how do you call it correctly?
What is LPCTSTR, and to what data type does it map in C#?
LPCTSTR is a typedef for const TCHAR*.
TCHAR is an attempt to abstract away the fact that the Windows API exists in both "ANSI" (char strings in a locale-specific encoding) and "Unicode" (UTF-16) versions.  There is no actual PdhOpenQuery function; there is a PdhOpenQueryA function that takes an ANSI string and a PdhOpenQueryW function that takes a UTF-16 string.
C# uses UTF-16 strings, so you'll want to prefer the "W" version of these functions.  Use PdhOpenQueryW.  Then the first parameter has C++ type const wchar_t*.  The C# type is [MarshalAs(UnmanagedType.LPWStr)] string.
How to map a pointer type DWORD_PTR? The pinvoke article says DWORD maps to UInt32, but how about pointers?
DWORD_PTR isn't a pointer.  It's an unsigned integer big enough to hold a pointer.  The equivalent C# type is System.UIntPtr.
I think PDH_STATUS and PDH_HQUERY are specific struct to the library (I'm not sure yet). how do I map these?
PDH_STATUS appears to be just an int.
PDH_HQUERY is a pointer to a handle (another pointer), but you can just pretend it's an integer and use IntPtr.
Putting it all together, your declaration should be:
[DllImport("Pdh.dll")]
static extern int PdhOpenQueryW(
    [MarshalAs(UnmanagedType.LPWStr)] string szDataSource, 
    UIntPtr dwUserData,
    out IntPtr phQuery);
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With