Comprendre les conflits Cdecl/__stdcall dans P/Invoke
P/Invoke, reliant C# et C , s'appuie sur des conventions d'appel correspondantes pour garantir une transmission appropriée des arguments et une gestion de la pile. Un problème courant survient lorsqu'une fonction C utilisant la convention __stdcall
est appelée à partir de C# en utilisant la convention P/Invoke par défaut (souvent cdecl
).
La racine du problème
Différentes conventions d'appel gèrent le nettoyage de la pile différemment :
__stdcall
: Largement utilisé dans les API Windows et COM, l'appelé (fonction C) est responsable du nettoyage de la pile.__cdecl
: La convention d'appel C par défaut, où l'appelant (code C#) gère le nettoyage de la pile.__thiscall
: Utilisé pour les fonctions membres C ; il n'est pas directement pris en charge dans P/Invoke en raison de sa complexité.Conséquences du décalage
Ajouter simplement extern "C"
au code C et spécifier CallingConvention.Cdecl
dans l'attribut C# DllImport
ne résoudra pas le problème. Les différentes responsabilités de nettoyage entraînent une corruption de la pile, provoquant potentiellement des plantages ou des erreurs subtiles et difficiles à déboguer, même sans avertissements immédiats du débogueur. La pile peut être nettoyée deux fois, entraînant un comportement imprévisible.
La solution : des conventions cohérentes
La clé est la cohérence. Modifiez la déclaration de la fonction C pour utiliser explicitement __cdecl
: remplacez extern "C" int __stdcall InvokedFunction(int);
par extern "C" int __cdecl InvokedFunction(int);
. Ensuite, assurez-vous que votre attribut C# DllImport
correspond :
<code class="language-csharp">[DllImport("CPlusPlus.dll", ExactSpelling = true, SetLastError = true, CallingConvention = CallingConvention.Cdecl)]</code>
Clé à retenir
Une attention particulière aux conventions d'appel est essentielle pour une interopérabilité P/Invoke fiable. L'utilisation de conventions cohérentes entre C et C# élimine les déséquilibres de pile et améliore la robustesse globale de votre code.
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!