L'utilisation de P / Invoke pour appeler les fonctions C de C # peut entraîner des accidents si les conventions d'appel ne correspondent pas. Cet article explore les raisons de ces conflits.
Les décalages des congrès d'appel et leurs effets
Un scénario commun implique une fonction C utilisant la convention __stdcall
, tandis que l'attribut C # DllImport
correspondant spécifie CallingConvention.Cdecl
. Cela se produit parce que:
__stdcall
: La convention d'appel standard pour les API Windows et de nombreuses fonctions C. La fonction appelée (callee
) est responsable du nettoyage de la pile. C'est la valeur par défaut p / invoque. __cdecl
: utilisé dans le code C. La fonction d'appel (caller
) est responsable du nettoyage de la pile. Le problème: empiler les déséquilibres
Lorsque l'appelant et la callee sont en désaccord sur le nettoyage de la pile, les déséquilibres de pile en résultent. Cela conduit à des accidents, à un comportement imprévisible et à un débogage peu fiable en raison des informations perdantes de la pile.
Autres conventions d'appels (et pourquoi elles comptent)
__thiscall
: utilisé en C pour les fonctions membres. Il n'est pas directement pris en charge dans .NET P / Invoke en raison des complexités de l'héritage et des différences de compilateur. __fastcall
: utilise des registres CPU pour le passage des arguments. Non pris en charge dans le code géré. __clrcall
: La convention du code géré, combinant des aspects de __stdcall
, __cdecl
et __fastcall
, avec des vérifications de sécurité d'exécution. Pourquoi la convention P / Invoke par défaut peut causer des problèmes
La convention d'appel P / invoque par défaut (stdcall
) s'affronte souvent avec le code C compilé à l'aide de __cdecl
. Cela découle de l'association historique de __stdcall
avec les API de Windows, conduisant à l'hypothèse (incorrecte) que toutes les fonctions C l'utilisent. Cette inadéquation provoque les problèmes de nettoyage de la pile décrits ci-dessus.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!