PInvokeStackImbalance C# appel pour le C++ la fonction

après être passé à VS2010, l'assistant de Débogage managé affiche une erreur au sujet d'une pile déséquilibrée d'un appel à une fonction C++ non gérée à partir d'une application C#.

La conventuelles suspects ne semblent pas être la cause du problème. Est-il autre chose que je doit vérifier? Le VS2008 construit C++ dll et C # application n'a jamais eu de problème, pas de bogues bizarres ou mystérieux - Oui, je sais que ça ne veut pas dire grand chose.

Voici les choses qui étaient vérifié:

  • le nom dll est correct.
  • le nom du point d'entrée est correct et a été vérifié avec depends.exe - le code doit utiliser le nom mutilé et il le fait.
  • la Convention d'appel est correcte.
  • les tailles et les types semblent tous corrects.
  • le jeu de caractères est correct.
  • il ne semble pas y avoir de problèmes après avoir ignoré la erreur et il n'y a pas de problème lors de la sortie du débogueur.

C#:

[DllImport("Correct.dll", EntryPoint = "SuperSpecialOpenFileFunc", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, ExactSpelling = true)]
public static extern short SuperSpecialOpenFileFunc(ref SuperSpecialStruct stuff);

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public struct SuperSpecialStruct
{
   public int field1;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
   public string field2;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
   public string field3;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
   public string field4;
   public ushort field5;
   public ushort field6;
   public ushort field7;
   public short field8;
   public short field9;
   public uint field10;
   public short field11;
};

C++:

short SuperSpecialOpenFileFunc(SuperSpecialStruct * stuff);

struct SuperSpecialStruct
{
   int               field1;
   char              field2[256];
   char              field3[20];
   char              field4[10];
   unsigned short    field5;
   unsigned short    field6;
   unsigned short    field7;
   short             field8;
   short             field9;
   unsigned int      field10;
   short             field11;
};

Voici l'erreur:

Assistant De Débogage Managé "PInvokeStackImbalance" a détecté un problème dans 'application Gérée chemin".

informations supplémentaires: un appel à Fonction PInvoke "SuperSpecialOpenFileFunc" déséquilibrée de la pile. C'est probable parce que la signature gérée PInvoke ne correspond pas à la cible non géré signature. Vérifiez que l'appel convention et paramètres de la Convention La signature de PInvoke correspond à la cible. signature non gérée.

38
demandé sur Phil Ross 2010-03-06 01:33:33

5 réponses

comme mentionné dans commentaire de Dane Rose , vous pouvez soit utiliser __stdcall sur votre fonction C++ ou déclarer CallingConvention = CallingConvention.Cdecl sur votre DllImport .

C'est la réponse qui résout mon problème.

59
répondu Graviton 2017-05-23 12:00:29

vous spécifiez stdcall en C# mais pas en C++, un décalage ici va conduire à la fois à la fonction et à la sortie des arguments de l'appelant de la pile.

d'un autre côté, il y a un commutateur de compilateur qui activera stdcall comme convention d'appel par défaut, (- Gz) utilisez-vous cela?

Ou essayez ceci dans votre C++

short __stdcall SuperSpecialOpenFileFunc(SuperSpecialStruct * stuff);
9
répondu John Knoeller 2010-03-06 02:59:33

vous ne spécifiez aucun remplissage dans votre déclaration C# de la struct, mais pas dans la version C++. Puisque vous mélangez des matrices de char qui ne sont pas toutes des multiples de 4 et un nombre impair de shorts de 2 Octets, le compilateur est probablement en train d'insérer du rembourrage dans la structure et d'ajouter la fin.

essayez d'envelopper la structure dans un #pragma pack pour vous assurer qu'il n'y a pas de rembourrage.

#pragma pack(push)
#pragma pack(1)

// The struct

#pragma pack(pop)
3
répondu Michael 2010-05-26 17:04:19

avait le même problème que décrit - application C++ non gérée qui a fonctionné parfaitement pendant des années. Lorsque nous sommes passés à VS2010,nous avons commencé à recevoir des messages équilibrés de Pinvokestack.

ajouter "_ _ stdcall " à la signature C++ comme décrit ci-dessus a fait disparaître le problème.

2
répondu user351059 2010-05-26 15:12:18

c'est bien.- Je mettre à jour la fonction définir comme suit:

[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]

ça marche bien.

1
répondu Vicky 2015-09-21 02:43:36