2008-10-14 8 views
2

J'intercepte les appels de l'API Win32 qu'un DLL ou un DLL natif effectue à partir de C# en utilisant une sorte d'accrochage. Dans ce cas particulier je suis intéressé par DrawText() dans user32.dll. Il est déclaré comme ceci dans l'API Win32:Accès aux membres de la structure Win32 C/C++ à partir du C#

INT WINAPI DrawTextW(HDC hdc, LPCWSTR str, INT count, LPRECT rect, UINT flags) 

Le struct LPRECT a la signature suivante (également dans l'API Win32):

typedef struct tagRECT { 
    LONG left; 
    LONG top; 
    LONG right; 
    LONG bottom; 
} RECT LPRECT; 

LONG est un typedef pour les entiers de 32 bits sur les systèmes 32 bits (n » Je ne sais pas sur les systèmes 64 bits, il est hors de propos à ce stade parce que je suis sur Windows 32 bits). Pour pouvoir accéder aux membres de cette struct je déclarais dans mon code C# ...

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
    public struct RECT 
    { 
     public Int32 left; 
     public Int32 top; 
     public Int32 right; 
     public Int32 bottom; 
    } 

... et a écrit la signature de P/Invoke en utilisant cette structure RECT:

[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true, CallingConvention = CallingConvention.StdCall)] 
static extern IntPtr DrawText(IntPtr HDC, String str, Int32 count, ref RECT rect, UInt32 flags, IntPtr dtp); 

Puisque les structures sont des types de valeurs en C# par opposition aux types de références comme en C/C++, le modificateur ref est nécessaire ici.

Cependant quand j'utilise rect.top rect.left etc., ils retournent presque toujours 0. Je sais pertinemment que c'est incorrect. Mais après avoir passé en revue d'innombrables heures et essayé beaucoup de choses différentes, je ne pouvais pas faire fonctionner ce truc simple.

choses que j'ai essayé:

  • En utilisant différentes primitives pour les membres de rect (int, long, court, UInt32 ...). En fait, il est un peu évident que ce n'est pas un problème de type car dans tous les cas je devrais voir des nombres tronqués, pas 0.
  • Suppression du modificateur ref. C'est aussi stupide (temps désespérés, mesures désespérées) car rect.left renvoie correctement le pointeur sur rect au lieu de sa valeur.
  • Essayé unsafe blocs de code. N'a pas fonctionné mais j'ai peut-être fait une erreur dans la mise en œuvre (je ne me souviens pas de ce que j'ai fait). En outre, cette approche est généralement réservée aux situations de pointeur difficiles dans COM et Win32, elle est de toute façon exagérée pour mon cas. Essayé d'ajouter [MarshallAs] avant les membres de RECT. N'a fait aucune différence. Joué avec Pack valeurs. Aucune différence.

Je suis assez sûr que je manque quelque chose très facile et simple, mais je ne sais pas ce qu'il est ...

Toute aide est appréciée. Je vous remercie.

Répondre

2

Je remarque que vous dites que vous avez essayé [MarshallAs] mais avez-vous essayé [MarshalAs(UnmanagedType.Struct)]?

1

Une partie du problème est l'utilisation de String où un StringBuilder doit être utilisé.

Essayez cette signature (Généré avec PInvoke Interop Assistant)


[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] 
public struct tagRECT { 

    /// LONG->int 
    public int left; 

    /// LONG->int 
    public int top; 

    /// LONG->int 
    public int right; 

    /// LONG->int 
    public int bottom; 
} 

public partial class NativeMethods { 

    /// Return Type: int 
    ///hdc: HDC->HDC__* 
    ///lpchText: LPCWSTR->WCHAR* 
    ///cchText: int 
    ///lprc: LPRECT->tagRECT* 
    ///format: UINT->unsigned int 
    [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint="DrawTextW")] 
public static extern int DrawTextW([System.Runtime.InteropServices.InAttribute()] System.IntPtr hdc, [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] System.Text.StringBuilder lpchText, int cchText, ref tagRECT lprc, uint format) ; 

} 
+0

Pourquoi nommer PInvoke Interop adjoint du tagRECT struct et non Üst RECT? – xx77aBs

Questions connexes