我正在尝试在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是库的特定结构(我还不确定)。我该如何映射这些?
什么是正确的方法声明,以及如何正确地调用它?
答案 0 :(得分:18)
什么是LPCTSTR,以及什么数据类型 它是用C#映射的吗?
LPCTSTR
是const 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函数调用,你就应该开展业务了。