Comment carte Win32 types de C# types lors de l'utilisation de P/Invoke?
Je suis en train de faire quelque chose comme cette en C#. J'ai trouvé comment appeler méthodes Win32 en C# à l'aide de P/Invoke à partir de ce lien. Cependant, j'ai rencontré quelques difficultés dans la mise en œuvre de P/Invoke.
Par exemple, l'une des méthodes que j'aimerais que l'accès est PdhOpenQuery,
signature:
PDH_STATUS PdhOpenQuery(
__in LPCTSTR szDataSource,
__in DWORD_PTR dwUserData,
__out PDH_HQUERY *phQuery
);
Je figure le C# correspondant déclaration doit être quelque chose comme ceci
[DllImport("Pdh.dll")]
static extern PDH_STATUS PdhOpenQuery(LPCTSTR szDataSource,
DWORD_PTR dwUserData, out PDH_HQUERY *phQuery);
Mes questions:
Qu'est-ce que LPCTSTR, et pour ce type de données est-il de la carte en C#?
Comment mapper un pointeur de type DWORD_PTR? Pinvoke article dit DWORD cartes à UInt32, mais comment sur les pointeurs?
Je pense que PDH_STATUS et PDH_HQUERY sont spécifiques struct à la bibliothèque (je ne suis pas encore sûr). comment puis-je faire correspondre ces?
Quelle est la bonne méthode de déclaration, et comment l'appelez-vous correctement?
Vous devez vous connecter pour publier un commentaire.
LPCTSTR
est un typedef pourconst TCHAR*
.TCHAR
est une tentative de faire abstraction du fait que l'API Windows existe dans les deux "ANSI" (char
chaînes de caractères dans un jeu de paramètres régionaux spécifiques à l'encodage) et "Unicode" (UTF-16) versions. Il n'y a pas de réellePdhOpenQuery
fonction; il y a unPdhOpenQueryA
fonction qui prend une chaîne ANSI et unPdhOpenQueryW
fonction qui prend une chaîne UTF-16 de la chaîne.C# utilise l'UTF-16 chaînes, de sorte que vous aurez envie de préférer le "W" de la version de ces fonctions. Utilisation
PdhOpenQueryW
. Alors le premier paramètre a C++ de typeconst wchar_t*
. Le type C# est[MarshalAs(UnmanagedType.LPWStr)] string
.DWORD_PTR
n'est pas un pointeur. C'est un unsigned entier assez grand pour tenir un pointeur. L'équivalent de type C# estSystem.UIntPtr
.PDH_STATUS
semble être juste unint
.PDH_HQUERY
est un pointeur sur une poignée (un autre pointeur), mais vous pouvez juste faire semblant que c'est un entier et d'utiliserIntPtr
.Mettre tous ensemble, votre déclaration doit être:
UIntPtr
devrait êtreUIntPtr dwUserData
? Une autre question, comment doit-on appeler la méthode?IntPtr
et ensuite utiliser lePtrToStringAnsi
ouPtrToStringUni
fonctions dans leSystem.Runtime.InteropServices.Marshal
classe à la chaîne.iirc LPCTSTR se décompose à:
LP == Pointeur Long //relique de 16 à 32 bits médiateur
C == Constante
TSTR == TStr //TString, un espace réservé qui aurait substitué de différents types de chaînes en fonction de divers C-têtes et #définit
ce que cela signifie pour vous: c'est un pointeur vers une chaîne de caractères, pour C# juste utiliser des chaînes de caractères et vous serez ok.
PDH_STATUS est un pointeur vers une DH_STATUS struct, de sorte que vous aurez besoin de définir une structure C# de match.
Découvrez P/Invoke.Net pour quelques exemples d'utilisation de p/invoke sur Windows standard, en-têtes, des structures et des fonctions. Le site web est une sorte de klunky, vous avez juste à garder en cliquant sur et en élargissant les éléments dans la colonne de gauche.
P/Invoke n'est pas bien documentée, mais une fois que vous avez la carte de la structure et de la fonction extern appel, vous devriez être dans les affaires.