EAccessViolation



  • Hallo zusammen, ich bekomme mal wieder eine EAccessViolation und weiss nicht warum... Code:

    bool __fastcall TProfibus::Identify(int Slave_int)
    {
    unsigned long dpr;
    unsigned int* n;
    ASYNC_RESULT AsyncResult;
    
    dpr=pDPIdentifySlave(Slave_int,n,false);
    PostMessage(Application->MainForm->Handle,MSG_TYPE_ASYNC,0,0);
    if (dpr != DP_INCOMPLETE)
      {
        dpr=pDPGetAsyncResult(&AsyncResult); // Funktionsaufruf --------> EXCEPTION
        if (dpr!= DP_NO_ERROR)               // Returnvalue-check
          {
          if (Main_Frm->lan)                 // Je nach aktueller Sprache, Fehler in De od. En ausgeben
            Application->MessageBox(AnsiString("Fehler beim identifizieren des Slaves.\nFehlernummer:" + AnsiString(dpr) + "\nBeschreibung:" + AnsiString(&result_ch[dpr][0])).c_str(), AnsiString("Fehler: "+AnsiString(dpr)).c_str(), 16);
          else
            Application->MessageBox(AnsiString("Error identify the slave.\nErrornumber:" + AnsiString(dpr) + "\nDescription:" + AnsiString(&result_ch[dpr][0])).c_str(), AnsiString("Error: "+AnsiString(dpr)).c_str(), 16);
          return 3;
          }
        else
          Application->MessageBox(AnsiString("Got async result! ID = "+ AnsiString::IntToHex(AsyncResult.uID,4)).c_str(),"",48);
      }
    return 0;
    
    }
    

    Aber hier funktioniert der Aufruf der Funktion pDPGetAsyncResult() ohne Probleme (ohne EAccessViolation):

    //Mehr Code
    ASYNC_RESULT AsyncResult;
        if (pDPGetAsyncResult(&AsyncResult) != DP_NO_ERROR)
          {
          if (Main_Frm->lan)                 // Je nach aktueller Sprache, Fehler in De od. En ausgeben
            Application->MessageBox(AnsiString("Fehler beim empfangen des async resultates.\nFehlernummer:" + AnsiString(dpr) + "\nBeschreibung:" + AnsiString(&result_ch[dpr][0])).c_str(), AnsiString("Fehler: "+AnsiString(dpr)).c_str(), 16);
          else
            Application->MessageBox(AnsiString("Error getting async result.\nErrornumber:" + AnsiString(dpr) + "\nDescription:" + AnsiString(&result_ch[dpr][0])).c_str(), AnsiString("Error: "+AnsiString(dpr)).c_str(), 16);
          return 4;
          }
    // Mehr Code
    

    Die Deklaration sieht so aus:

    typedef unsigned long (__declspec (dllimport) DPGetAsyncResultDll)(ASYNC_RESULT);
       DPGetAsyncResultDll* pDPGetAsyncResult;
    //---------und...
      pDPGetAsyncResult = (DPGetAsyncResultDll*)::GetProcAddress(hInstance, "DPGetAsyncResult");
      if (!pDPGetAsyncResult)
        {
         Application->MessageBox(AnsiString("Fehler bei der Adressierung der Funktion \"pDPGetAsyncResult\"\nFehler#:" + AnsiString(GetLastError())).c_str(), "Fehler",16);
        }
    

    Die Fehlermeldung lautet: 'Zugriffsverletztung bei Adresse 00000000. Lesen von Adresse 00000000.'
    Könnt Ihr mir helfen? Danke!!!!!!!!



  • Ist die Adresse von "pDPGetAsyncResult" vor der Voilation gültig?

    -junix



  • junix schrieb:

    Ist die Adresse von "pDPGetAsyncResult" vor der Voilation gültig?

    -junix

    ja, sieht so aus: Wert: 10004600
    das ist doch eine gültige Adresse oder...?
    [edit]Schreibfehler korrigiert[/edit]



  • Der Header sieht gesamt übrigens so aus:

    //---------------------------------------------------------------------------
    #ifndef TProfibusH 
    #define TProfibusH
    
    #include <vcl.h>
    
    //---------------------------------------------------------------------------
    typedef struct
           {
               // PKW(Parameter-Kennung-Wert)
    
               unsigned short      PKE;        // Parameter-Kennung
               unsigned short      IND;        // Subindex, Unter-Parameternummner, Array-Index
               unsigned short      PWE1;       // Parameter-Wert 1. Wort
               unsigned short      PWE2;       // Parameter-Wert 2. Wort
    
               // PZD(Prozess-Daten)
    
               unsigned short      PZD1;       // Prozess-Daten 1. Wort
               unsigned short      PZD2;       // Prozess-Daten 2. Wort
               // m.t.13
               // PZD(Prozess-Daten)
               }PPO1;
    
               // PPO type 1 (Octet string 12)
    
           typedef struct
              {
              // PKW(Parameter-Kennung-Wert)
    
              unsigned short     PZD6;          // Prozess-Daten 6. Wort
              unsigned short     PZD5;          // Prozess-Daten 5. Wort
              unsigned short     PZD4;          // Prozess-Daten 4. Wort
              unsigned short     PZD3;          // Prozess-Daten 3. Wort
              unsigned short     PZD2;          // Prozess-Daten 2. Wort
              unsigned short     PZD1;          // Prozess-Daten 1. Wort
    
              // PZD(Prozess-Daten)
    
              unsigned short      PWE2;         // Parameter-Wert 1. Wort
              unsigned short      PWE1;         // Parameter-Wert 2. Wort
              unsigned short      IND;          // Subindex, Unter-Parameternummner, Array-Index
              unsigned short      PKE;          // Parameter-Kennung
    
              }PPO2;
    //---------------------------------------------------------------------------
    class TProfibus
    {
    public:
           __fastcall TProfibus(void);
           __fastcall ~TProfibus(void);
           int __fastcall Init(int SlaveID_int, unsigned int uPort);
           bool __fastcall StopCommunication(void);
           bool __fastcall GetAnswer(void);
           bool __fastcall DpeGetAnswer(void);
           bool __fastcall ReceiveMessages(void);
           bool __fastcall OperationMenu(void);
           bool __fastcall DpeOperationMenu(void);
           bool __fastcall Identify(int Slave_int);
           bool __fastcall ReadSlave(int Slave_int);
    
           int __fastcall SendData(PPO1*, int paramnum);
            /* Data structure for cyclic PROFIBUS DP operations */
           typedef struct
           {
           unsigned char 	NormParameters [7];		/* set on startup: norm parameter. Ident number is read from slave */
           unsigned char 	UserParamLength;		/* set on startup: user parameter length */
           unsigned char 	UserParameters [248];	        /* set on startup: user parameter */
           unsigned char 	ConfigLength;			/* set on startup: configuration length, 0==read config from slave */
           unsigned char 	Configuration  [256];	        /* set on startup: configuration */
           unsigned char 	OutputLength;			/* automatically set by DPOpenSlave() : output length */
           unsigned char 	OutputData     [256];	        /* set on startup and with DPWriteSlaveData(): output data to send */
           unsigned char 	InputLength;			/* receive: input length */
           unsigned char 	InputData      [256];	        /* receive: input data */
           unsigned char 	NormDiagnosis  [6];		/* receive: norm diagnosis */
           unsigned char 	UserDiagLength;			/* receive: user diag length */
           unsigned char 	UserDiagnosis  [256];	        /* receive: user diagnosis */
           BOOL			bCommunicate;		/* receive: slave is communicating (TRUE) */
           BOOL			bOperate;				/* receive: slave is in state operate (TRUE) */
           BOOL			bNewDiag;				/* receive: new diag data ,cleared by DPReadSlaveData() */
           } DP_DATA;
    
    private:
    
            typedef enum
            {
    	CMD_OPEN = 0,						/* command open slave */
    	CMD_CLOSE,							/* command close slave */
    	CMD_GETCFG,							/* command get cfg */
    	CMD_SENDPRM,						/* command send parameter */
    	CMD_IDENTIFY,						/* command get ident number */
    	CMD_ADDR,							/* command change address */
            } CMD_TYPES;
    
           #define	MSG_TYPE_ASYNC		0x0001		/* async. operation finished, LPARAM=holds operation ID */
           #define	MSG_TYPE_DPCYCLE	0x0002		/* This message is sent, after completion of one PROFIBUS DP cycle */
           #define	MSG_TYPE_DPE		0x0004		/* message on DPE confirmation or indication */
           typedef enum
            {
    	DP_NO_ERROR = 0x0000,		        /* no error */
    	DP_GENERIC_ERROR,			/* generic error */
    	DP_CALLED_TWICE,			/* DP function have been called double (only with DPSetDispatchMessage()) */
    	DP_OPEN_FAILED,				/* device (FDL) opening failed */
    	DP_FDL_LOAD_FAILED,			/* unable to load FDL library */
    	DP_NOT_OPEN,				/* FDL not opened */
    	DP_THREAD_ENABLED,			/* error, background thread enabled: function disabled */
    	DP_NO_THREAD_ENABLED,		        /* error, background thread is not enabled: function disabled */
    	DP_OUT_OF_MEMORY,			/* out of memory */
    	DP_CONVERTER_FAILED,		        /* PROFIBUS converter not found, failed or bad type */
    	DP_ILL_ADDRESS,				/* illegal DP slave address */
    	DP_SAP_OPEN_FAILED,			/* PROFIBUS SAP opening failed */
    	DP_SLAVE_OPEN,				/* slave is allread open */
    	DP_SLAVE_NOT_OPEN,			/* slave is not opened */
    	DP_SLAVE_NOT_FOUND,			/* slave not found */
    	DP_ILLEGAL_CONFIG,			/* illegal PROFIBUS configuration */
    	DP_CFG_ERROR,				/* sconfiguration error on startup */
    	DP_PRM_ERROR,				/* parameter error on startup */
    	DP_CFG_AND_PRM_ERROR,		        /* configuration and parameter error on startup */
    	DP_BAD_LENGTH,				/* data length incorrect */
    	DP_INCOMPLETE,				/* background operation initiated: use DPGetAsyncResult() for answer. High word holds operation ID */
    	DP_NORESULT,				/* no background operation finished DPGetAsyncResult() */
            } DP_RESULT;
    
           typedef struct
           {
    	CMD_TYPES		uCmd;					/* initiate command type */
    	unsigned int	uID;					/* id code of operation (high byte of DP_INCOMPLETE result) */
    	DP_RESULT		ResultCode;				/* result error code of operation */
    											/* union holding result for serveral commands: */
    	union
    	{
    		struct								/* result of DPOpenSlave() CMD_OPEN */
    		{
    			DP_DATA			pDpData;		/* result slave data */
    		} Open;
    		struct								/* result of DPGetCfg() CMD_GETCFG */
    		{
    			unsigned char	ucLength;		/* result config length */
    			unsigned char	Buffer[256];	/* result configuration */
    		} GetCfg;
    		struct								/* result of DPIdentifySlave() CMD_IDENTIFY */
    		{
    			unsigned int	uIdentNumber;	/* result ident number */
    		} Ident;
    	} Data;
           } ASYNC_RESULT;
    
    };
    //---------------------------------------------------------------------------
    #endif
    


  • Und die Adresse entspricht auch dem was GetProcAddress da zurückgegeben hat? (übrigens sollte man in C++-Programmen C-Style-Casts meiden und lieberr die C++-Casts (*_cast) verwenden.

    -junix



  • junix schrieb:

    Und die Adresse entspricht auch dem was GetProcAddress da zurückgegeben hat? (übrigens sollte man in C++-Programmen C-Style-Casts meiden und lieberr die C++-Casts (*_cast) verwenden.

    -junix

    hm, ja, der Wert ist der selbe.
    und was meinst du genau mit den casts? wie sollte ich das genau lösen?
    pDPReadSlaveData = static_cast<DPReadSlaveDataDll*>(GetProcAddress(hInstance, "DPReadSlaveData"));
    so etwa?



  • Hallo,

    Da der Rückgabewert von GetProcAddress wohl ein void Pointer ist müsste es schon ein reinterpret_cast sein.

    Ciao



  • Okay, vielen Dank, das gecaste sieht jetzt so aus:

    pDPGetAsyncResult = reinterpret_cast<DPGetAsyncResultDll*>(GetProcAddress(hInstance, "DPGetAsyncResult"));
      if (!pDPGetAsyncResult)
        {
         Application->MessageBox(AnsiString("Fehler bei der Adressierung der Funktion \"pDPGetAsyncResult\"\nFehler#:" + AnsiString(GetLastError())).c_str(), "Fehler",16);
        }
    

    Die AccessViolation erscheint aber immerno genau gleich. 😞



  • und ja, die Funktions deklaration sieht wie folgt aus:

    typedef unsigned long (__declspec (dllimport) DPGetAsyncResultDll)(ASYNC_RESULT);
       DPGetAsyncResultDll* pDPGetAsyncResult;
    

    Da warnt der Compiler: "Stil der Funktionsdefinition ist nun veraltet".
    Ich weiss nicht warum, aber vielleicht liegts ja daran.
    Danke!



  • Versuch's mal so:

    typedef unsigned long (__declspec (dllimport) *DPGetAsyncResultDll)(ASYNC_RESULT); 
    DPGetAsyncResultDll pDPGetAsyncResult;
    


  • WebFritzi schrieb:

    Versuch's mal so:

    typedef unsigned long (__declspec (dllimport) *DPGetAsyncResultDll)(ASYNC_RESULT); 
    DPGetAsyncResultDll pDPGetAsyncResult;
    

    Kommt genau die selbe Warnung... 😞


Anmelden zum Antworten