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

Vue hybride

gibsam System.AccessViolationExceptio... 28/12/2010, 13h50
bacelar Vous êtes sûr que... 31/12/2010, 00h04
gibsam Comment puis-je être sûr que... 03/01/2011, 10h26
MABROUKI std::string 03/01/2011, 21h15
bacelar Moi, je préfère aller à la... 03/01/2011, 22h44
gibsam Les chaînes sont en ANSI.... 04/01/2011, 15h58
gibsam Merci pour cette réponse mais... 16/02/2011, 16h38
bacelar Size est égale à combien ?... 17/02/2011, 01h41
gibsam Effectivement, j'avais oublié... 23/02/2011, 17h30
bacelar 8O Dur Dur l'orthographe tard... 23/02/2011, 23h02
Message précédent Message précédent   Message suivant Message suivant
  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 474
    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 474
    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 474
    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 474
    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
    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 :

  9. #9
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 474
    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 474
    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.

  10. #10
    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.

  11. #11
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 474
    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 474
    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