IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++/CLI Discussion :

System.AccessViolationException avec c_str


Sujet :

C++/CLI

  1. #1
    Membre habitu�
    Profil pro
    Inscrit en
    D�cembre 2010
    Messages
    13
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2010
    Messages : 13
    Par d�faut System.AccessViolationException avec c_str
    Bonjour,

    J'essaie de coder une application pour utiliser une cam�ra GigE Basler Scout. Pour cela j'utilise visual studio 2008 et le SDK fourni par le fabriquant. L'application est bas�e sur les windows form en C++/CLI.

    J'ai un probl�me lorsque j'essaie de r�cup�rer l'adresse IP de la cam�ra. Le SDK pr�voit une m�thode GetIPAddress pour cela. Celle-ci me retourne un objet de type Pylon::String_t.

    Ce type permet de faire appel � des fonctions utilis�es par les std::string comme c_str. Dans le but d'afficher le r�sultat dans un label, je cherche � passer le r�sultat en System::String via :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    System::String ^sIP = gcnew System::String(pBgdi.GetIpAddress().c_str());
    La compilation se passe sans probl�me mais j'ai une erreur � l'ex�cution. Je me retrouve avec :

    Une exception non g�r�e du type 'System.AccessViolationException' s'est produite dans TestPylonNET.exe

    Informations suppl�mentaires*: Tentative de lecture ou d'�criture de m�moire prot�g�e. Cela indique souvent qu'une autre m�moire est endommag�e.
    alors que sIP prend bien la valeur voulue (adresse en XXX.XXX.XXX.XXX)

  2. #2
    Expert confirm�
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    F�vrier 2005
    Messages
    5 507
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : France, Val de Marne (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : F�vrier 2005
    Messages : 5 507
    Par d�faut
    Vous �tes s�r que "pBgdi.GetIpAddress().c_str()" contient un caract�re fin de cha�ne correcte ?

  3. #3
    Membre habitu�
    Profil pro
    Inscrit en
    D�cembre 2010
    Messages
    13
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2010
    Messages : 13
    Par d�faut
    Comment puis-je �tre s�r que le caract�re en fin de chaine est correct ? Car si j'ai bien compris, le dernier caract�re de chaine doit �tre '\0', mais je n'arrive pas � trouver comment l'obtenir.

  4. #4
    Membre extr�mement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    D�tails du profil
    Informations personnelles :
    �ge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par d�faut std::string
    bonjour,
    quand tu dis les std::string,pour les chaines standat en c++ il y a 2 cas du au fourbi qui distingue Ansi(1 octet) et Unicode(widechar=2 octets).
    en utilisant le namespace std et avec la meme chaine on a :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #include <string>
    using namespace std;
    void main()
    {
    	//Ansi String
    	string szAnsiString;
    	szAnsiString = "c:\\Program Files\\Microsoft Visual Studio .Net";
     
    	//Wide Char String
    	wstring wszWCharString;
    	wszWCharString = L"c:\\Program Files\\Microsoft Visual Studio .Net";
    }
    Le "string^ c++/cli " lui c'est de l'unicode.
    Il faudrait caster en widecar peut etre avant de convertir en "string^" de c++/cli.
    bon code...

  5. #5
    Expert confirm�
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    F�vrier 2005
    Messages
    5 507
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : France, Val de Marne (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : F�vrier 2005
    Messages : 5 507
    Par d�faut
    Moi, je pr�f�re aller � la source.

    Dans le d�buggeur de VS (menu Debug de VS), il y a des vues "memory".

    S�lectionnez en une et mettez l'adresse retourn�e par "pBgdi.GetIpAddress().c_str()". Vous verrez la zone m�moire contenant la cha�ne, vous verrez comment elle est encod�e et si le caract�re de fin de cha�ne est bien pr�sent.

  6. #6
    Membre habitu�
    Profil pro
    Inscrit en
    D�cembre 2010
    Messages
    13
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2010
    Messages : 13
    Par d�faut
    Les cha�nes sont en ANSI. J'ai essay� le cast en wide char, mais je me retrouve avec la m�me erreur. En utilisant la vue memory pour le r�sultat de GetIPAddress().c_str(), j'obtiens :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    0x04C97F78  0d f0 ad ba 31 39 32 2e 31 36 38 2e 31 2e 35 00 0d f0 ad ba  .ð*º192.168.1.5..ð*º
    Il y a bien la valeur '00' dans la m�moire allou�e � cette chaine, si je ne me trompe pas dans mon interpr�tation.

    Ce qui est relativement bizarre, c'est que lorsque j'utilise d'autres fonctions de la m�me classe, me retournant des objet de m�me type (Pylon::String_t), la conversion en System::String ^ fonctionne; comme par exemple :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    String ^sVendor = gcnew System::String(pBgdi.GetVendorName().c_str());
    En me servant de la vue m�moire pour cette cha�ne classique pBgdi.GetVendorName().c_str(), j'obtiens :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    0x05F10FF0  00 00 00 00 cd cd cd cd 42 61 73 6c 65 72 00 cd cd cd cd cd  ....ÍÍÍÍBasler.ÍÍÍÍÍ
    De plus, lorsque je passe en release, tout fonctionne... L'erreur obtenue en debug est une erreur premi�re chance. Je n'arrive pas � trouver � quoi cela correspond et comment passer outre...

  7. #7
    Membre habitu�
    Profil pro
    Inscrit en
    D�cembre 2010
    Messages
    13
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2010
    Messages : 13
    Par d�faut Work around via try{} .. catch {}
    J'ai fini par trouv� un moyen pour faire fonctionner le code en DEBUG. Tout simplement :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    		try
    		{
    			sIP = gcnew System::String(pBgdi.GetIpAddress().c_str());
    		}
    		catch(Exception ^)
    		{
    		}

  8. #8
    Expert confirm�
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    F�vrier 2005
    Messages
    5 507
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : France, Val de Marne (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : F�vrier 2005
    Messages : 5 507
    Par d�faut
    Le DEBUG montre que vous faites des b�tises mais vous lui clouez le bec.
    Ne vous �tonnez pas si la machine se venge.

    Vous tripatouillez au mauvais endroit en m�moire, v�rifiez votre code.

  9. #9
    Membre habitu�
    Profil pro
    Inscrit en
    D�cembre 2010
    Messages
    13
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2010
    Messages : 13
    Par d�faut
    Je me doute bien que ce n'est pas la meilleure fa�on de g�rer le probl�me. Mais je ne suis jamais arriv� � le r�soudre.

    Il y a certainement une r�gle du C++/CLI qui m'�chappe. Si vous pouviez m'indiquer laquelle, je vous en serai tr�s reconnaissant.

  10. #10
    Expert confirm�
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    F�vrier 2005
    Messages
    5 507
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : France, Val de Marne (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : F�vrier 2005
    Messages : 5 507
    Par d�faut
    AccessViolationException ne vient pas du code manag� mais du code natif, qui ne change pas avec C++/CLI.

    Utilisez les techniques de d�buggages standards, C++/CLI ne change pas la mani�re de faire.

    Activez l'arr�t de votre programme via la configuration du d�buggeur de VS, lors du lancement de cette exception "AccessViolationException".

    "menu de VS" -> "Debug" -> "Exceptions" -> "Native ..." -> "cochez dans le ligne correspondant AccessViolationException et la colonne "throw".

    Le d�buggeur vous montrera le code qui g�n�re cette exception.

  11. #11
    Membre habitu�
    Profil pro
    Inscrit en
    D�cembre 2010
    Messages
    13
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2010
    Messages : 13
    Par d�faut
    Dans mon Visual, les AccessViolation Exception sont dans les Win32 Exception. J'ai d�j� effectu� cette partie du Debug (mais ne suis pas aller beaucoup plus loin faute de connaissances dans le domaine ); Toujours est-il que l'exception est lev�e � chaque manipulation de chaine donn�es r�seau de la cam�ra ( � savoir : Adresse IP, Default Gateway, Masque sous r�seau et adresse Mac). Le probl�me ne se pr�sente pas avec d'autres donn�es de m�me type (Pylon::String_t), lui-m�me d�rivant de std::string.
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    			try
    			{
    				sMacro = gcnew System::String(pBgdi.GetMacAddress().c_str());
    			}
    Le pointeur d'instructions lors de la lev�e d'instruction pointe sur l'accolade de fermeture. Les adresses donn�e dans la fen�tre sortie sont les suivantes :

    Exception de premi�re chance � 0x007ee138 dans Scout_MultiSpectrale_Beta_v0.01.exe*: 0xC0000005: Violation d'acc�s lors de la lecture de l'emplacement 0x43303329.
    Lorsque je vais voir ces deux adresses (0x007ee138 et 0x43303329), dans la vue m�moire, elles sont vides ( ce qui est peut �tre normal ...).

    Bref, je ne vois pas trop o� chercher...

  12. #12
    Expert confirm�
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    F�vrier 2005
    Messages
    5 507
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : France, Val de Marne (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : F�vrier 2005
    Messages : 5 507
    Par d�faut
    Avez-vous v�rifi� dans votre cas, que vous n'�tiez pas dans la situation d�crite par la troisi�me phrase de la section "Notes" de la documentation MSDN du constructeur d'une System::String ?

    http://msdn.microsoft.com/fr-fr/library/6y4za026.aspx

  13. #13
    R�dacteur/Mod�rateur
    Avatar de JolyLoic
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    5 463
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 51
    Localisation : France, Yvelines (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 5 463
    Par d�faut
    c_str retourne une cha�ne termin�e par 0, il n'y a pas le choix.

    Pour transformer des cha�nes entre natif et manag�, le plus simple je trouve est d'utiliser marshal_as :

    http://msdn.microsoft.com/en-us/library/bb384865.aspx

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    #include <marshal_cppstd.h>
     
    using namespace msclr::interop;
     
     
    String^ sMacro = marshal_as<String^>( pBgdi.GetMacAddress() );
    Ma session aux Microsoft TechDays 2013 : D�velopper en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage � la d�couverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'h�sitez pas � me contacter.

  14. #14
    Expert confirm�
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    F�vrier 2005
    Messages
    5 507
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : France, Val de Marne (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : F�vrier 2005
    Messages : 5 507
    Par d�faut
    Merci Lo�c pour cette r�ponse concise.
    Mais je crois que justement, si la cha�ne est foireuse, c'est le "c_str()" qui plantera.

    Avec le nouveau code, je pense que "marshal_as<String^>" plantera (et heureusement, si la cha�ne est foireuse).

    Donc commencez par v�rifier la qualit� de la cha�ne retourn�e par "pBgdi.GetMacAddress()". J'aurais jamais confiance dans une API qui donne une adresse MAC sous forme de cha�ne de caract�re, pour moi c'est un entier 48 bits, voir un tableau d'octet, mais pas une string.

  15. #15
    Membre habitu�
    Profil pro
    Inscrit en
    D�cembre 2010
    Messages
    13
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2010
    Messages : 13
    Par d�faut
    Voil� ce que j'obtiens dans la vue m�moire � l'adresse o� est �crite ma chaine adresse MAC :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    0x04D63078  0d f0 ad ba 30 30 33 30 35 33 30 43 36 35 43 35 00 f0 ad ba  .ð*º0030530C65C5.ð*º
    Si je ne me trompe pas dans la lecture, l'adresse MAC de ma cam�ra (0030530C65C5) est bien suivi de la valeur 00.

    Cependant tout les sympt�mes d'une cha�ne mal cod�e que vous d�crivez Bacelar sont pr�sents (le marshal_as m'a retourn� l'exception).

    Autre fait notable, lorsque je code :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    Pylon::String_t Mac = pBgdi.GetMacAddress();
    sMacro = gcnew System::String(Mac.c_str());
    Le tout passe mais une exception AccessViolation est lev�e � la sortie de la fonction.

  16. #16
    Expert confirm�
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    F�vrier 2005
    Messages
    5 507
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : France, Val de Marne (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : F�vrier 2005
    Messages : 5 507
    Par d�faut
    Bingo.

    MSDN indique qu'il faut fournir un pointeur sur un tableau de caract�res Unicode
    http://msdn.microsoft.com/en-us/library/6y4za026.aspx

    Or, votre dump m�moire montre une cha�ne de caract�re termin� par un simple '\0' (correcte pour une cha�ne ASCII) et non le double caract�re Unicode '\0\0'.

    Nous sommes en pr�sence d'une cha�ne ASCII et non du cha�ne UNICODE.

    Il vous reste donc � choisir une solution qui permette de r�gler ce probl�me.
    - Utilisez une API type "GetMacAddress" en version Unicode
    - Convertir la cha�ne ASCII en cha�ne Unicode
    - Utilisez les constructeurs de string ASCII friendly comme http://msdn.microsoft.com/en-us/library/ezh7k8d5.aspx ou encore mieux http://msdn.microsoft.com/en-us/library/9d876whe.aspx
    - etc...

  17. #17
    Membre habitu�
    Profil pro
    Inscrit en
    D�cembre 2010
    Messages
    13
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2010
    Messages : 13
    Par d�faut
    Merci pour cette r�ponse mais il y a encore des choses qui m'�chappent. L'API ne fournissant pas de m�thode retournant une chaine Unicode, j'ai choisit de faire appel � un constructeur prenant en compte l'encodage d'origine :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    System::Text::Encoding ^ascii = System::Text::Encoding::ASCII;
    size_t size = pBgdi.GetMacAddress().size();
    System::String ^Mac = gcnew System::String(pBgdi.GetMacAddress().c_str(), 0, size, ascii);
    label_MacAdress->Text = "Mac Address :  " + Mac;
    Seulement, � l'appel du constructeur de System::String comme d�crit http://msdn.microsoft.com/en-us/library/9d876whe.aspx, j'obtiens toujours la m�me exception.

    Autre fait �trange, si je souhaite r�cup�rer une autre donn�e, comme le nom du vendeur de la cam�ra, j'obtiens en dump:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    0x060705A0  00 00 00 00 cd cd cd cd 42 61 73 6c 65 72 00 cd cd cd cd cd  ....ÍÍÍÍBasler.ÍÍÍÍÍ
    La chaine se termine donc encore par un '\0'. Mais il n'y a pas de probl�me si je code :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    sVendor = gcnew System::String(pBgdi.GetVendorName().c_str())
    Donc encore une fois :

  18. #18
    Expert confirm�
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    F�vrier 2005
    Messages
    5 507
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : France, Val de Marne (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : F�vrier 2005
    Messages : 5 507
    Par d�faut
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    size_t size = pBgdi.GetMacAddress().size();
    Size est �gale � combien ?
    Oui, je n'est aucune confiance dans "GetMacAddress()".

    This constructor processes characters from value starting at startIndex and ending at (startIndex + length - 1).
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    System::String ^Mac = gcnew System::String(pBgdi.GetMacAddress().c_str(), 0, size, ascii);
    Il vous manquerait pas un "size+1" � la place de "size" ?

    La chaine se termine donc encore par un '\0'.
    Vous ne plantez pas parce que vous avec qu'un '\0' mais parce qu'il n'y a pas de '\0\0' avant la fin de la page m�moire allou�e au programme par l'OS.

  19. #19
    Membre habitu�
    Profil pro
    Inscrit en
    D�cembre 2010
    Messages
    13
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2010
    Messages : 13
    Par d�faut
    Effectivement, j'avais oubli� le size + 1. Mais cela n'a pas r�solu l'exception. Apr�s contact avec le constructeur de la cam�ra et d�veloppeur API, il s'av�re que cette m�thode retournant ne peux �tre utilis�e que lorsque l'objet cam�ra n'a pas �t� instanci�, point non pr�cis� dans la doc fournit ou, tout du moins, que je n'ai pas vu( et ce n'est pas faute de l'avoir parcouru...). Une fois le device instanci�, il convient d'utiliser :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
     
    int64 Mac =pCamera->GevMACAddress();
    int64 IP = pCamera->GevCurrentIPAddress();
    Code retournant un entier, ce qui est bien plus pratique pour l'interpr�tation et affichage.

  20. #20
    Expert confirm�
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    F�vrier 2005
    Messages
    5 507
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : France, Val de Marne (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : F�vrier 2005
    Messages : 5 507
    Par d�faut
    Oui, je n'estai aucune confiance dans "GetMacAddress()".
    Dur Dur l'orthographe tard le soir.



    Je l'avais bien dit que cette API ne sentait pas bon du tout.

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. Probl�me avec l'exception System.AccessViolationException
    Par inter_amine dans le forum Windows Forms
    R�ponses: 8
    Dernier message: 08/12/2008, 15h48
  2. [VC++] System TrayIcon avec QT
    Par yelbied dans le forum MFC
    R�ponses: 4
    Dernier message: 29/11/2005, 10h46
  3. [Système]communiquer avec un processus externe sous windows
    Par tweety dans le forum G�n�ral Java
    R�ponses: 4
    Dernier message: 14/11/2005, 17h17
  4. [systeme] - pb avec deux OS Win 98 et WIN XP
    Par rico_49 dans le forum Windows XP
    R�ponses: 1
    Dernier message: 24/10/2005, 14h25
  5. R�ponses: 13
    Dernier message: 20/06/2005, 14h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo