Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Warum verursacht diese Zeile eine AV? (https://www.delphipraxis.net/51595-warum-verursacht-diese-zeile-eine-av.html)

Daniel G 15. Aug 2005 20:17


Warum verursacht diese Zeile eine AV?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Es gibt Programme, die man schreibt, die verfolgen einen 'ne verdammt lange Zeit. "Be S.M.A.R.T." ist so eines davon.

Welche Zeile ich meine? Diese hier:

Delphi-Quellcode:
 pAttrBuffer := PChar(PSENDCMDOUTPARAMS(AttrOutCmd).bBuffer[0]); //Zeile 73
Ich hab' das Beispiel - Projekt mit allen notwendigen Dateien angehängt. Ich würde mich freuen, wenn man mir helfen könnte. Das Programm in Einzelteilen hier hinein zu kopieren, würde keinen Sinn machen. Es muss doch irgendwie gehen... :cry:

ichbins 15. Aug 2005 20:27

Re: Warum verursacht diese Zeile eine AV?
 
Ich weiss hier jetzt zwar auch nicht weiter aber ich mache es normalerweise immer so, dass ich die entsprechende Zeile mit showmessage-Meldungen suche und dann aufsplitte

var
c:char;
begin
c:=PSENDCMDOUTPARAMS(AttrOutCmd).bBuffer[0];
pattrbuffer:=pchar(c);

und so weiter... vielleicht hilft das ja...

marabu 15. Aug 2005 21:13

Re: Warum verursacht diese Zeile eine AV?
 
Hallo Daniel,

müsste das nicht eher so aussehen:

Delphi-Quellcode:
pAttrBuffer := PChar(@PSENDCMDOUTPARAMS(@SCOP).bBuffer);
Auch die Zeile danach sieht sehr suspekt aus...

Verstehe auch nicht warum du da mit PChar arbeitest.

Grüße vom marabu

Olli 15. Aug 2005 21:19

Re: Warum verursacht diese Zeile eine AV?
 
Hmmm ... irgendwie sagt mein Delphi "Invalid Stream Format" ... kannst du mir helfen? :stupid:

Scherz beseite ... was soll denn das bitte sein?
Delphi-Quellcode:
PChar(PSENDCMDOUTPARAMS(AttrOutCmd).bBuffer[0]);
:shock: ... bei mir ist AttrOutCmd == 16 ... kein Wunder also, daß das abkackt. Du castest hier den Wert 16 in einen Pointer auf eine Struktur und versuchst auf ein Element dieser Struktur (von der du sagst sie sei an Adresse 0x00000010) zuzugreifen. Du landest damit großzügig in der Nullpointerseite des Systems.

Erklär mal was du willst.

EDIT: hab ich doch den marabu übersehen ... tut mir sorry :mrgreen:

Übrigens kann man dann ja auch gleich zB schreiben:
Delphi-Quellcode:
      pAttrBuffer := @SCOP.bBuffer[0];
oder sogar:
Delphi-Quellcode:
      pAttrBuffer := SCOP.bBuffer;
... nee, also das letzte mag er nicht, da bräuchtest du wohl wieder einen Typecast ...

marabu 15. Aug 2005 21:30

Re: Warum verursacht diese Zeile eine AV?
 
Hi Olli,

bin auch schon drauf gekommen. Habe zwar keine Doku aber das sieht vielversprechend aus:

Delphi-Quellcode:
var
  pAttrBuffer: PDRIVEATTRIBUTE;
begin
  ...
        pAttrBuffer := @SCOP.bBuffer;
  ...
end;
marabu

Olli 15. Aug 2005 21:41

Re: Warum verursacht diese Zeile eine AV?
 
Zitat:

Zitat von marabu
bin auch schon drauf gekommen. Habe zwar keine Doku aber das sieht vielversprechend aus

Stimmt. Ohne Verweis auf das erste Arrayelement geht's natürlich auch. Ist halt Angewohnheit bei mir ;)

Daniel G 15. Aug 2005 22:22

Re: Warum verursacht diese Zeile eine AV?
 
Hmm... Ok, die AV ist weg. Mal sehen, wie das jetzt weiter geht....

Ich hatte mich an dem orig. Microsoft - Code orientiert:

Code:
DoPrintData(((PSENDCMDOUTPARAMS)AttrOutCmd)->bBuffer,
      ((PSENDCMDOUTPARAMS)ThreshOutCmd)->bBuffer,
                     i);
"DoPrintData" ist dabei wie folgt deklariert:

Code:
VOID DoPrintData(PCHAR pAttrBuffer, PCHAR pThrsBuffer, BYTE bDriveNum)
int   i;
PDRIVEATTRIBUTE   pDA;
PATTRTHRESHOLD   pAT;
BYTE Attr;

   //
   // Print the drive number
   //
   printf("\nData for Drive Number %d\n", bDriveNum);
   //
   // Print the revisions of the data structures
   //
   printf("Attribute Structure Revision         Threshold Structure Revision\n");
   printf("            %d                                     %d\n\n",
            (WORD)pAttrBuffer[0],
            (WORD)pThrsBuffer[0]);

   //
   // Print the header and loop through the structures, printing
   // the structures when the attribute ID is known.
   //
   printf("  -Attribute Name-      -Attribute Value-     -Threshold Value-\n");

   pDA = (PDRIVEATTRIBUTE)&pAttrBuffer[2];
   pAT = (PATTRTHRESHOLD)&pThrsBuffer[2];

   for (i = 0; i < NUM_ATTRIBUTE_STRUCTS; i++)
   {
      Attr = pDA->bAttrID;
      if (Attr)
      {
         if (Attr > MAX_KNOWN_ATTRIBUTES)
            Attr = MAX_KNOWN_ATTRIBUTES+1;
         printf("%2X %-29s%d%20c%d\n",
               pDA->bAttrID,
               pAttrNames[Attr],
               pDA->bAttrValue,
               ' ',
               pAT->bWarrantyThreshold );
      }
      pDA++;
      pAT++;
   }

}
Zum Testen habe ich mir die erste Variable geschnappt:

Delphi-Quellcode:
pAttrBuffer: PChar
Und dann dachte ich halt, das obige würde in Delphi so aussehen:
Delphi-Quellcode:
PChar(PSENDCMDOUTPARAMS(AttrOutCmd).bBuffer[0])
Oder hab' ich das damit völlig verhauen? Ich mochte "C" noch nie....

Olli 15. Aug 2005 22:30

Re: Warum verursacht diese Zeile eine AV?
 
Zitat:

Zitat von Daniel G
Oder hab' ich das damit völlig verhauen? Ich mochte "C" noch nie....

Jupp. Aber ohne die Deklaration für AttrOutCmd zu kennen, können wir auch mit deinem C-Codebeispiel nix machen ... also die Diagnose wird wohl ausbleiben müssen. Das kann in C formal korrekt sein, aber die Delphiversion war's nicht.

Daniel G 15. Aug 2005 22:33

Re: Warum verursacht diese Zeile eine AV?
 
Zitat:

Zitat von Olli
Aber ohne die Deklaration für AttrOutCmd zu kennen...

Kein Problem:

C:

Delphi-Quellcode:
#define READ_ATTRIBUTE_BUFFER_SIZE   512
BYTE   AttrOutCmd[sizeof(SENDCMDOUTPARAMS) + READ_ATTRIBUTE_BUFFER_SIZE - 1];
Und ...naja... halt dasselbe in Delphi:

Delphi-Quellcode:
const
   READ_ATTRIBUTE_BUFFER_SIZE = 512;
var
AttrOutCmd   : Byte = BYTE(sizeof(TSENDCMDOUTPARAMS) + (READ_ATTRIBUTE_BUFFER_SIZE - 1));

Olli 15. Aug 2005 22:40

Re: Warum verursacht diese Zeile eine AV?
 
Zitat:

Zitat von Daniel G
Delphi-Quellcode:
const
   READ_ATTRIBUTE_BUFFER_SIZE = 512;
var
AttrOutCmd   : Byte = BYTE(sizeof(TSENDCMDOUTPARAMS) + (READ_ATTRIBUTE_BUFFER_SIZE - 1));

Nope, eher:
Delphi-Quellcode:
const
   READ_ATTRIBUTE_BUFFER_SIZE = 512;
var
AttrOutCmd   : array[0.. BYTE(sizeof(TSENDCMDOUTPARAMS) + (READ_ATTRIBUTE_BUFFER_SIZE - 1))]of Byte;
Willst du genau wissen was du gemacht hast? Ein Byte kann Werte von 0..255 halten. 512 ist 0 + 512 ist dementsprechend wieder 0 in den Grenzen eines Bytes. Daher enthielt dein Byte den Wert sizeof(TSENDCMDOUTPARAMS)-1 oder so ...


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:13 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz