Question

Je suis p / invoque à CreateRectRgn dans gdi32.dll. La signature normale p / invoque pour cette fonction est:

[DllImport("gdi32", SetLastError=true)]
static extern IntPtr CreateRectRgn(int nLeft, int nTop, int nRight, int nBottom);

En tant que raccourci, j'ai également défini cette surcharge:

[DllImport("gdi32", SetLastError=true)]
static extern IntPtr CreateRectRgn(RECT rc);

[StructLayout(LayoutKind.Sequential)]
struct RECT{
    public int left;
    public int top;
    public int right;
    public int bottom;
}

(Oui, je suis conscient de CreateRectRgnIndirect, mais comme je dois utiliser des fonctions pour convertir entre System.Drawing.Rectangle et ça RECT Structure, ce qui précède est plus utile pour moi, car elle n'implique pas une variable intermédiaire.)

Cette surcharge devrait fonctionner de manière identique à la signature normale, car elle devrait mettre la pile dans un état identique à l'entrée pour CreateRectRgn. Et en effet, sur Windows XP, 32 bits, cela fonctionne parfaitement. Mais sur Windows 7, 64 bits, la fonction renvoie zéro et Marshal.GetLastWin32Error() Renvoie 87, qui est «le paramètre est incorrect».

Des idées sur ce qui pourrait être le problème?

Était-ce utile?

La solution

Oh. La convention d'appel que Microsoft utilise sur x64 est totalement différent de stdcall. Dans l'appel à CreateRectRgn, la pile n'est pas du tout utilisée pour les paramètres, ils sont tous passés dans les registres. Quand j'essaye de passer un RECT Structure, il fait une copie de la structure de la pile et met un pointeur sur cette copie dans un registre. Par conséquent, cette petite astuce ne fonctionnera pas du tout dans des fenêtres 64 bits. Maintenant, je dois passer par tout mon code d'interopération et trouver d'autres endroits où j'ai fait cela et les retirer tous.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top