83 votes

pinvokestackimbalance - comment puis-je résoudre ce problème ou l’éteindre?

Je viens de passé à vs2010 de vs2008. Exactement la même solution, sauf que maintenant chaque appel à une dll C++ donne un 'pinvokestackimbalance' exception.

Cette exception ne pas me faire virer en 2008. - Je avoir l'accès complet à la dll C++ et à l'application appelante. Il ne semble pas y avoir de problème avec la pinvoke, mais ce problème est de faire du débogage d'autres problèmes impossibles; l'IDE est d'arrêter constamment à me dire au sujet de ces choses.

Pour exemple, voici le C# signature:

    [DllImport("ImageOperations.dll")]
    static extern void FasterFunction(
        [MarshalAs(UnmanagedType.LPArray)]ushort[] inImage, //IntPtr inImage, 
        [MarshalAs(UnmanagedType.LPArray)]byte[] outImage, //IntPtr outImage, 
        int inTotalSize, int inWindow, int inLevel);

Voici à quoi il ressemble sur le C++ côté:

#ifdef OPERATIONS_EXPORTS
#define OPERATIONS_API __declspec(dllexport)
#else
#define OPERATIONS_API __declspec(dllimport)
#endif
extern "C" {


OPERATIONS_API void __cdecl FasterFunction(unsigned short* inArray, 
                                       unsigned char* outRemappedImage,
                                       int inTotalSize, 
                                       int inWindow, int inLevel);

}

Quelle est la différence entre vs2010 et vs2008 qui serait la cause de ces exceptions pour obtenir jetés? Dois-je ajouter un autre ensemble de paramètres pour la DllImport directive?

156voto

Stephen Cleary Points 91731

Tout d'abord, comprendre que le code est faux (et l'a toujours été). Le "pInvokeStackImbalance" n'est pas une exception en soi, mais un gérés assistant débogage. Il a été désactivée par défaut dans VS2008, mais beaucoup de gens n'ont pas, de sorte qu'elle est activée par défaut dans VS2010. La MDA n'est pas exécuté en mode de diffusion, de sorte qu'il ne se déclenche pas si vous construisez pour la libération.

Dans votre cas, la convention d'appel est incorrect. DllImport par défaut est CallingConvention.WinApi, qui est identique à l' CallingConvention.StdCall pour les architectures x86 code bureau. Il convient CallingConvention.Cdecl.

49voto

JGogel Points 141

Pour l'éteindre:

  1. CTRL + ALT + E
  2. Sous "Assistants de débogage gérés", décochez PInvokeStackImbalance.

8voto

Vijay Kumbhoje Points 11

Mieux pour résoudre ce problème, ce n'est pas beaucoup difficile ici, je suis de mentionner certaines de ces méthodes, il peut même que certains de mes amis mentionné ci-dessus. Je suis en train de travailler avec PCSC une carte à puce de l'application j'ai passer une semaine environ, obtenir énervé a fait beaucoup de changements finalement obtenu les solutions.

Pour moi, son travail avec PInvoke Extension lequel j'ai installé pour VS2010 vous pouvez le télécharger ici http://www.red-gate.com/products/dotnet-development/pinvoke/

Le télécharger et l'installer, Fermez visual studio et ouvrez de nouveau, vous pouvez trouver l'extension de la Barre de Menu. enter image description here

Si l'erreur est à cause de la signature ne correspond pas à vous suffit de cliquer sur PInvoke.net> Insérer PInvoke Signatures

La nouvelle fenêtre apparaîtra comme ci-dessous enter image description here

Entrez le nom de la dll et cliquez sur recherche, vous pouvez voir l'ensemble des fonctions de cette dll dans la fenêtre des résultats de recherche, Cliquez sur la fonction que vous obtiendrez une signature pour cette Fonction particulière.

Utilisez cette signature et vous avez besoin de modifier vos programmes selon que la Signature, Principalement le Type de données.

Ce résoudre mon problème que vous pourriez avoir, le problème est différent comme callingConvention ou d'autres attributs besoin de le spécifier lors de l'importation dll.

Amusez-vous bien!

3voto

penguinman Points 21

J'ai eu ce problème lors de l'utilisation de VS2010. Ce qu'il est: Visual Studio par défaut est 64 bits de code pour 'CPU'. Les pointeurs vers des variables (par exemple. des chaînes) est désormais devenu 64 bits lors de l'appel de votre Dll, où que l'ensemble de vos fiable et de confiance utiliser Dll 32 bits pointeurs.

Ne pas supposer qu'il ya quelque chose de mal avec votre Dll, il n'y en a pas.

Changer votre VS les paramètres pour générer X86 code comme ceci (Express versions de C#)

  1. allez dans Outils -> Options.
  2. Dans le coin inférieur gauche de la boîte de dialogue Options, cochez la case qui dit, "Afficher tous les paramètres".
  3. Dans l'arborescence sur le côté gauche, sélectionnez "Projets et Solutions".
  4. Dans les options sur la droite, cochez la case qui dit, "Show advanced construire configuraions."
  5. Cliquez sur OK.
  6. Allez Construire -> Gestionnaire de Configuration...
  7. Dans la Plate-forme de colonne à côté de votre projet, cliquez sur la liste déroulante et sélectionnez "".
  8. Dans la "Nouvelle plate-forme", choisir "x86".
  9. Cliquez sur OK.
  10. Cliquez Sur Fermer.

Je remarque d'ailleurs, que même si les ordinateurs ont doublé en puissance tous les 12 mois, mon ordinateur actuel avec 1gig de RAM, semble pas plus vite que pour mon premier 486 avec 4 Meg. Ne vous inquiétez pas à l'aide de 64 bits de code, il ne va pas être plus rapide ou mieux, parce qu'il est construit sur un énorme objet encombrant orientée tour de la météorisation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X