2010-12-01 4 views
3

Je suis en utilisant Visual Studio 2010.C++ std :: string Paramètre <Bad Ptr>

J'ai une classe avec le constructeur suivant:

CVideoAnnotation::CVideoAnnotation(std::string aPort, DWORD aBaudRate) 

Je crée une instance de CVideoAnnotation comme suit:

CVideoAnnotation cVideoAnnotation("COM3", CBR_9600); 

'CBR_9600' est une macro qui décide de 9600.

vers le bas dans la con structor, aBaudRate est 9600 comme prévu. Cependant, aPort n'est pas transmis correctement. Lorsque je passe le curseur dessus, IntelliSense donne une valeur de <Bad Ptr>.

Est-ce que quelqu'un a des idées sur pourquoi la chaîne ne passe pas correctement?

Merci, Dave

Comme une mise à jour à ma question initiale, j'ajoute le code de montage pour l'appel du constructeur et la population de la population locale une fois à l'intérieur du constructeur.

CVideoAnnotation cVideoAnnotation("COM3", CBR_9600); 
0041177D push  2580h 
00411782 sub   esp,20h 
00411785 mov   ecx,esp 
00411787 mov   dword ptr [ebp-174h],esp 
0041178D push  offset string "COM3" (4198C8h) 
00411792 call  std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> > (41131Bh) 
00411797 mov   dword ptr [ebp-17Ch],eax 
0041179D lea   ecx,[ebp-11h] 
004117A0 call  dword ptr [__imp_CVideoAnnotation::CVideoAnnotation (41D4DCh)] 
004117A6 mov   dword ptr [ebp-180h],eax 
004117AC mov   dword ptr [ebp-4],0 





CVideoAnnotation::CVideoAnnotation(std::string aPort, DWORD aBaudRate) 
{ 
100137F0 push  ebp 
100137F1 mov   ebp,esp 
100137F3 push  0FFFFFFFFh 
100137F5 push  offset [email protected]@[email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected] (1001DC82h) 
100137FA mov   eax,dword ptr fs:[00000000h] 
10013800 push  eax 
10013801 sub   esp,164h 
10013807 push  ebx 
10013808 push  esi 
10013809 push  edi 
1001380A push  ecx 
1001380B lea   edi,[ebp-170h] 
10013811 mov   ecx,59h 
10013816 mov   eax,0CCCCCCCCh 
1001381B rep stos dword ptr es:[edi] 
1001381D pop   ecx 
1001381E mov   eax,dword ptr [___security_cookie (10026090h)] 
10013823 xor   eax,ebp 
10013825 mov   dword ptr [ebp-10h],eax 
10013828 push  eax 
10013829 lea   eax,[ebp-0Ch] 
1001382C mov   dword ptr fs:[00000000h],eax 
10013832 mov   dword ptr [ebp-18h],ecx 
10013835 mov   dword ptr [ebp-84h],0 
1001383F mov   dword ptr [ebp-4],0 
+0

Je ne vois aucun pointeur explicite dans votre code, il est donc possible que vous corrompiez la pile quelque part. – casablanca

+0

Je m'étais demandé à ce sujet; Cependant, la toute première chose qui se passe dans _tmain() est la construction CVideoAnnotation montrée dans mon post original. (_tmain() est le point d'entrée pour une application de console Windows avec un en-tête précompilé.) Avant cela, stdafx.h, iostream, conio.h et VideoAnnotation.h sont inclus. À son tour, le fait VideoAnnotation.h: #pragma une fois #include #define WIN32_LEAN_AND_MEAN #include #ifdef EXPORTING_DLL #define DECL_DLL __declspec (dllexport) #else #define DECL_DLL __declspec (dllimport) # endif – Dave

Répondre

0

"COM3" est pas un std :: string est un const char *, essayez de créer un std :: string pour passer.

+0

'std :: string' a un constructeur qui prend un' const char * '. – casablanca

+2

Le passage d'une chaîne std :: string donne le même résultat. Dans tous les cas, std :: string a un constructeur de conversion const char *; l'appeler de la manière dont je l'ai est conforme aux normes. – Dave

+0

Comme casablanca mentionné ci-dessus cVideoAnnotation ("COM3", CBR_9600) est absolument correct syntaxiquement puisqu'il crée un objet chaîne implicite. Bien sûr, si le constructeur attendait une chaîne et que le code ne serait pas compliqué (dans ce cas, nous devons utiliser une chaîne const et à la place) – JohnP

4

Si vous implémentez CVideoAnnotation dans une DLL séparée vous ont un problème bien connu de franchissement des limites de la DLL lors de l'utilisation de conteneurs STL. Pour vérifier que cela est le cas créer un nouveau constructeur de prendre un const char * au lieu de std :: string et essayer ..

Une autre chose, au lieu de std :: string préfèrent utiliser const std :: string &

+0

Je franchis en effet une frontière DLL. Je vais essayer votre suggestion afin de déterminer si c'est le problème. Mais je vais quand même demander ... Y at-il une solution de contournement qui n'implique pas de changer la signature du constructeur? Je n'ai pas la propriété de ce constructeur et je ne suis pas libre de le changer (sauf dans une expérience locale). – Dave

+0

Passer le C-string travaillé. Je suis apparemment frapper ce problème de limites DLL STL. Je commence à google autour pour apprendre sur ce problème et voir si il existe une solution de contournement qui me permettrait de laisser la signature constructeur inchangée ... – Dave

+0

Essayez ce lien Dave: http://support.microsoft.com/kb/172396/fr-fr/J'ai été confronté à ce problème il y a plusieurs années en utilisant VC++ 6.0 .. Il a été documenté depuis MSDN depuis et je pensais qu'il aurait été corrigé ... Si je ne me trompe pas quand j'ai commencé à utiliser stlport au lieu de STL de Plaunger (par défaut VS) le problème a disparu – JohnP

2

Le passage de string vers et à partir de DLL devrait fonctionner correctement. Comme noté ci-dessus, l'utilisation de conteneurs STL de cette manière peut être problématique, mais string est bien.

Avez-vous des preuves au-delà de Intellisense que la chaîne est foirée? Dans les versions Release, Intelliesnse peut être sommaire. Essayez d'ajouter cout << aPort << endl; dans ce constructeur pour vous assurer. Si elle est vraiment incorrecte, je déboguerais simplement de l'appelant dans l'appel du constructeur - voir où le string est poussé en tant que paramètre, et voir d'où il provient de la pile à utiliser dans le constructeur. Quelque chose doit être désynchronisé ici, en supposant que DLL et application utilisent la même version des runtimes C++, et vous devriez être capable de dire pourquoi en inspectant le code assembleur.

+0

Oui, la chaîne est vraiment mauvaise (cout entraîne une violation d'accès). J'ai ajouté quelque chose à mon post original et j'essaye de le comprendre maintenant. – Dave

0

Je luttais aussi contre ce qui ressemblait à un mauvais alignement des octets. Basé sur les suggestions ici que traverser les limites de la bibliothèque peut être problématique, je soupçonne (même si j'utilise une bibliothèque statique au lieu de DLL) que je pourrais avoir affaire au même genre de problème. J'instanciais une classe dans une bibliothèque dont le code était dans un autre. Lorsque j'ai déplacé l'instanciation dans la bibliothèque où son code était le problème est parti. Je ne comprends pas pourquoi cela a fonctionné mais au moins je peux maintenant aller de l'avant.

Questions connexes