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 :

Access Violation : Tentative de lecture ou écriture de mémoire partagée


Sujet :

C++/CLI

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur Optique - Vision
    Inscrit en
    Janvier 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur Optique - Vision
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3
    Points : 1
    Points
    1
    Par défaut Access Violation : Tentative de lecture ou écriture de mémoire partagée
    Bonjour à tous,
    Je sollicite votre aide à propos d'une intégration hardware qui me pose réellement des soucis. Je m'explique :
    Dans le cadre d'une application je dois intégrer une nouvelle caméra dans un environnement C++/CLI et c'est là que je pêche... (Je suis plus habitué au code natif et autres MFC).

    Bien entendu, les sources/DLL de la caméra est en natif et je tiens à vous dire que le code sur lequel je travaille n'est pas de moi : il est réellement rude et barbare (static dans tous les sens...) pour mon oeil non averti...

    J'ai une DLL managée (et un namespace) qui regroupe les fonctions initialisation, snap de la cam... : (au passage je tiens à signaler que les sources de cette DLL tournent sans problème avec une appli native)

    DLL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    static void CameraBasler::InitColorCam(CameraColor* Cam,size_t &BufferSize,CLogBasler ^pLog);
    static voidCameraBasler::InitBufferCam(CameraColor* Cam,CLogBasler ^pLog);
    static bool CameraBasler::Snap(CameraColor* Cam,System::Drawing::Bitmap^% bmp,CLogBasler ^pLog);
    }

    Lorsque je lance ces deux fonctions successivement je plante en access violation avec Tentative de lecture ou écriture de mémoire partagée.

    J'ai une structure CameraColor qui ressemble à ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    struct CameraColor	
    {
    	Pylon::CBaslerGigECamera	                 m_CamColor;
    	Pylon::CBaslerGigECamera::StreamGrabber_t  m_StreamGrabber;
            static const size_t                                 m_ImageSize=5045424;
    	uint8_t                                                 m_Buffer[m_ImageSize];
    	StreamBufferHandle                                m_hBuffer;
    } ;
    Le but est de faire tourner la caméra en créant le "nécessaire" (comme une brute dans l'appli principale)
    Je sais c'est très moche! (A ma décharge, j'ai repris cette architecture bouchère de la part du précédent développeur et en passant par des objets de classe l'erreur persistait...)

    Du Coup, dans le Load de ma Form, je passe sans encombre la première fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
     
    public ref class CameraBasler
    {
    void CameraBasler::InitColorCam(CameraColor* Cam,size_t &BufferSize,CLogBasler ^pLog) 
    {
    try
    	{
    		Pylon::PylonAutoInitTerm autoInitTerm;
    		// Get the transport layer factory
    		CTlFactory& TlFactory = CTlFactory::GetInstance();
    		// Create the transport layer object needed to enumerate or
    		// create a camera object of type Camera_t::DeviceClass()
    		ITransportLayer *pTl = TlFactory.CreateTl(Pylon::CBaslerGigECamera::DeviceClass());
    		// Exit the application if the specific transport layer is not available
    		if (! pTl)
    		{
    			pLog->AddString("Error : Failed to create transport layer!",true);
    			return;
    		}
    		// Get all attached cameras and exit the application if no camera is found
    		DeviceInfoList_t devices;
    		if (0 == pTl->EnumerateDevices(devices))
    		{
    			pLog->AddString("Error : No Basler Camera Present!",true);
    			return ;
    		}
    		// Create the camera object of the first available camera.
    		// The camera object is used to set and get all available
    		// camera features.
    		Cam->m_CamColor.Attach(pTl->CreateDevice(devices[0]));
     
    		bool bTest = false;
    		if(Cam->m_CamColor.IsAttached())
    		{
    			// Open the camera
    			Cam->m_CamColor.Open();
    			if(Cam->m_CamColor.IsOpen())bTest = true;
    		}
     
    		// Get the first stream grabber object of the selected camera
    			Cam->m_StreamGrabber.Attach(Cam->m_CamColor.GetStreamGrabber(0));
    			bTest = Cam->m_StreamGrabber.IsAttached();
     
    			// Open the stream grabber
    			Cam->m_StreamGrabber.Open();
    			bTest = Cam->m_StreamGrabber.IsOpen();
     
    			// Set the image format and AOI
    			Cam->m_CamColor.PixelFormat.SetValue(PixelFormat_BayerBG8);
    			Cam->m_CamColor.OffsetX.SetValue(0);
    			Cam->m_CamColor.OffsetY.SetValue(0);
    			Cam->m_CamColor.Width.SetValue(Cam->m_CamColor.Width.GetMax());
    			Cam->m_CamColor.Height.SetValue(Cam->m_CamColor.Height.GetMax());
     
    			//Disable acquisition start trigger if available
    			{
    				GenApi::IEnumEntry* acquisitionStart = Cam->m_CamColor.TriggerSelector.GetEntry( TriggerSelector_AcquisitionStart);
    			if ( acquisitionStart && GenApi::IsAvailable( acquisitionStart))
    			        {
    				     Cam->m_CamColor.TriggerSelector.SetValue( TriggerSelector_AcquisitionStart);
    				     Cam->m_CamColor.TriggerMode.SetValue( TriggerMode_Off);
    				}
    			}
     
    		//Disable frame start trigger if available
    		{
    			GenApi::IEnumEntry* frameStart =Cam->m_CamColor.TriggerSelector.GetEntry( TriggerSelector_FrameStart);
    			if ( frameStart && GenApi::IsAvailable( frameStart))
    			{
    				Cam->m_CamColor.TriggerSelector.SetValue( TriggerSelector_FrameStart);
    				Cam->m_CamColor.TriggerMode.SetValue( TriggerMode_Off);
    			}
    		}
    		//Set acquisition mode
    		Cam->m_CamColor.AcquisitionMode.SetValue(AcquisitionMode_SingleFrame);
     
    		//Set exposure settings
    		Cam->m_CamColor.ExposureMode.SetValue(ExposureMode_Timed);
    		Cam->m_CamColor.ExposureTimeRaw.SetValue(100);
    		// Create an image buffer
    		BufferSize = (size_t)(Cam->m_CamColor.PayloadSize.GetValue());
    	}
    	 catch (GenICam::GenericException &e)
    	{
    		// Error handling
    		pLog->AddString("Error : An exception occurred!",true);
    		return ;
    	}
    }
    Mais lorsque j'arrive à la ligne en gras , ça se corse :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    void CameraBasler::InitBufferCam(CameraColor* Cam,CLogBasler ^pLog)
    	{
    		int iSize = Cam->m_ImageSize;
    		// We won't use image buffers greater than ImageSize
    		Cam->m_StreamGrabber.MaxBufferSize.SetValue(iSize,false);
    
    		// We won't queue more than one image buffer at a time
    		Cam->m_StreamGrabber.MaxNumBuffer.SetValue(1);
    
    		// Allocate all resources for grabbing. Critical parameters like image
    		// size now must not be changed until FinishGrab() is called.*/
    		Cam->m_StreamGrabber.PrepareGrab();
                    ....
             }
    Plus précisément planté au code ligne suivante (source du fournisseur de Caméra)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    virtual void SetValue(int64_t Value, bool Verify = true)
            {
                if(ref::m_Ptr)
                    return ref::m_Ptr->SetValue(Value, Verify);
                else
                    throw ACCESS_EXCEPTION("Feature not present (reference not valid)");
            }
    Première chose : je ne suis pas doué pour m'exprimer...
    Ensuite, je répète, les mêmes fonctions de la DLL tournent à partir d'une base vierge...

    Questions : (en vrac)
    Une idée de la provenance de mes soucis ?
    Comment peut-on créer un pointeur d'une classe managée que l'on pourrait gérer comme en natif (allocation/désallocation) ?

    Meric d'avance, et je vous prie d'être indulgent sur mon niveau, svp...

  2. #2
    Futur Membre du Club
    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
    Points : 5
    Points
    5
    Par défaut
    Bonjour,

    Je suis un débutant en programmation C++/CLI et je développe aussi une application pour une caméra Basler, via leur SDK Pylon.

    Voilà la solution que j'ai adopté :

    Je déclare un pointeur vers un objet camera et un pointeur vers un objet StreamGrabber dans le .h :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	public: Camera_t::StreamGrabber_t *pStreamGrabber;
    	public: Camera_t *pCamera;
    Sachant que le type Camera_t est une redéfinition de CBaslerGigECamera.

    ensuite, dans le form1.cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    pStreamGrabber = new Camera_t::StreamGrabber_t (pCamera->GetStreamGrabber(0));
    		pStreamGrabber->Open();
     
    		//definition des paramètres du StreamGrabber
    		pStreamGrabber->MaxBufferSize= ImageSize;
    		pStreamGrabber->MaxNumBuffer= 1;
    Ce qui ne m'amène aucune exception. Mon idée était d'adapté au c++/cli toute la démarche d'acquisition donnée dans l'aide de Pylon pour c++.

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur Optique - Vision
    Inscrit en
    Janvier 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur Optique - Vision
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Cher gibsam,

    Tout d'abord je te remercie pour la réponse... Même si j'avais essayé (presque naturellement) cette solution de prime abord, je l'ai (re)codé sans aucune avancée..

    Ainsi en ayant dans form1.h, les objets suivants :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Camera_t::StreamGrabber_t *m_pStreamGrabber;
    Camera_t *m_pCamera;
    uint8_t* m_pBuffer;
    StreamBufferHandle m_hBuffer;
    les fonctions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    void InitCamera(void);
    void DestroyCamera(void);
    instanciées pour la première dans le constructeur et dans le destructeur pour la seconde j'obtiens une exception! de type
    System Violation Exception
    avec le message inscrit dans le titre du topic.

    Pour être plus précis l'erreur déclenche à DeregisterBuffer(...) première fonction Pylon appelée par mon DestroyCamera().

    Je tiens à préciser que les deux fonctions utilisent uniquement le code fourni pour le SDK Pylon (SingleFrame précisément)...

    Je suis un peu perdu...

    Autre chose : J'ai essayé de lancer DestroyCamera() dans le finalizer, à ce stade le code ne plante pas mais sur la sortie je récupère une flopée d'erreurs de première chance...
    De plus, il m'est impossible (tout de même) de lancer une fonction type Snap (
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    m_pCamera->AcquisitionStart.Execute();
    ) sans retrouver la même erreur...

    Je voudrais savoir s'il y a des options de compilation qui pourrait être responsable de ce type d'erreurs... En effet, je reprends un vieux projet "pourri" alors que le départ d'une solution vierge WinForm semble ne pas provoquer cette erreur !

    Si une idée arrive, je suis (vraiment) preneur !

    Merci d'avance

  4. #4
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur Optique - Vision
    Inscrit en
    Janvier 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur Optique - Vision
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Juste des petits renseignements à titre indicatif :
    1. La flopée d'exception de première chance évoquée plus haut n'est pas corrélée à mon problème.
    Raison : Le source originelle que je viens de reprendre les a également (Quand je vous dis que le projet original, c'est du joli ! ) .

    2. Lorsque je crée une fonction qui alloue mes objets caméras, effectue une prise d'image et détruit mes objets, et que cette fonction est lancée à partir du constructeur je n'ai aucune erreur mémoire...

    Par contre, lorsque je scinde en une fonction d'init démarrée au constructeur + une fonction Snap sur évènement bouton + une fonction Destroy dans le destructeur de classe l'erreur
    Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
    réapparaît !!

    Je viens de vérifier toutes les options de compilation (elles sont identiques au prog. vierge qui tourne où j'ai également scindé selon les 3 fonctionnalités décrit plus haut...)

    Du coup, je dois dire que je sèche...

    Peut-être est-ce une notion C++/CLI que je n'appréhende pas bien ??

    Merci d'avance à tous

Discussions similaires

  1. Réponses: 2
    Dernier message: 09/07/2010, 13h31
  2. Réponses: 5
    Dernier message: 25/01/2010, 11h35
  3. Réponses: 3
    Dernier message: 30/06/2009, 15h45
  4. Accesse Violation lors de lecture d'une vidéo
    Par jad777 dans le forum C++Builder
    Réponses: 9
    Dernier message: 23/10/2008, 00h14
  5. Réponses: 4
    Dernier message: 15/07/2007, 00h07

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