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.
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.
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);
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)
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.
c'est bien.- Je mettre à jour la fonction définir comme suit:
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
ça marche bien.