PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Parsen von Memory


Matrix316
2006-12-19, 18:42:10
Nehmen wir mal an ich habe einen Zeiger auf einen Speicherbereich, wie kann ich jedes einzelne Byte rausbekommen, so wie es im Speicher drinnen steht? Sprich, wenn ich 2000 Bytes an Daten habe, wie bekomm ich mit einer Schleife die einzelnen Bytes raus?

Ich hab schonmal was mit malloc und memcpy und sprintf versucht, aber das stürzt dann ab beim Ausführen.

Fruli-Tier
2006-12-19, 18:49:52
Vielleicht liest Du aus Bereichen, von denen Du die Finger lassen sollst!?

Ansonsten ist memcpy Dein Freund.

Matrix316
2006-12-19, 18:59:16
memcpy hab ich ja schon, aber danach mach ich irgendwas falsch. Hier mal der Code:



HRESULT Transform(IMediaSample *pSample)
{
LONG samplesize = pSample->GetActualDataLength();
ui64 *pInt = NULL;

BYTE *pbVideo;
pSample->GetPointer(&pbVideo); //Zeiger auf Buffer mit Daten

pInt = (ui64*) malloc(samplesize);
char *str = (char*) malloc(samplesize);


memcpy(pInt,pbVideo,samplesize);

int index=0;

while (index<samplesize)
{
sprintf( str, "%x", pInt[index]);

FILE *pFile = fopen("c:\\values.txt","a+");


fputs(str,pFile);
fclose(pFile);
index++;
}
return NOERROR;
}

Neomi
2006-12-19, 19:19:25
Du indizierst pInt mit einem Wert, der dem Offset in Bytes entsprechen soll. Da der Datentyp aber 8 Bytes groß ist, wird der Offset mit 8 multipliziert und du greifst weit außerhalb des angeforderten Speichers zu. Das kann nur abstürzen. Nebenbei hast du noch zwei Speicherlecks in der Funktion.

Ändere den Typ von pInt in "unsigned char *" und gib die beiden Speicherblöcke wieder frei vor dem Rücksprung. Die zweite Speicheranforderung ist völlig unnötig, da du keinen String mit dynamischer Länge brauchst, sondern einen konstant langen. Eine Sicherheitsabfrage nach der Speicheranforderung sehe ich auch nicht. Die Datei solltest du einmal vor der Ausgabeschleife öffnen und danach einmal schließen, nicht in jedem Durchlauf. Und am Ende solltest du die führenden Nullen nicht unterschlagen, wenn du eine brauchbare Ausgabe willst. Bei unsigned char wäre das "%02x".

Matrix316
2006-12-19, 19:31:10
Kannst du vielleicht mal ein paar Zeilen schreiben wie du das lösen würdest?:rolleyes:

Neomi
2006-12-19, 20:32:21
Kannst du vielleicht mal ein paar Zeilen schreiben wie du das lösen würdest?:rolleyes:

OK, meine Lösung sähe so aus:

HRESULT Transform (IMediaSample * pSample)
{
static const char * pDigits = "0123456789ABCDEF";

char * pOut;
unsigned char * pData;
size_t Size;
size_t Size2;

pSample->GetPointer (&pData);
Size = pSample->GetActualDataLength ();

Size2 = Size + (Size >> 2) + (Size >> 6);

pOut = new char [Size2];
Size2 = 0;

for (size_t i = 0; i < Size; ++i)
{
if ((i > 0) && ((i & 3) == 0))
{
if ((i & 63) != 0)
{
pOut [Size2++] = ' '; // Leerzeichen alle 4 Bytes
}
else
{
pOut [Size2++] = '\r'; // Zeilenumbruch alle 64 Bytes
pOut [Size2++] = '\n';
}
}

pOut [Size2++] = pDigits [pData [i] >> 4];
pOut [Size2++] = pDigits [pData [i] & 15];
}

// Todo: Daten rausschreiben (Daten: pOut, Größe: Size2)

delete [] pOut;

return (NOERROR);
}

Ungetestet, sollte aber auf Anhieb funktionieren. Beim Rausschreiben aber darauf achten, daß keine terminierende '\0' vorhanden ist.

Matrix316
2006-12-19, 21:12:37
Hm, kompilieren geht, aber beim start stürzt es ab.

EDIT: Eine Frage: Die Zeilen :

pOut [Size2++] = pDigits [pData [i] >> 4];
pOut [Size2++] = pDigits [pData [i] & 15];

Verstehe ich nicht. Wie kommst du da an die Daten im Speicher auf den pData zeigt?

Matrix316
2006-12-20, 00:32:14
Irgendwie ist mir das so zu komplizert. Mal eine andere Variante:


cPTSf->samplesize = pSample->GetActualDataLength();

BYTE *pbVideo;
pSample->GetPointer(&pbVideo);


BYTE value=NULL;
int i=0;
char str[3];

FILE *pFile = fopen("c:\\values.txt","a+");
while (i<cPTSf->samplesize)
{
value = 0;
value = *pbVideo; //1. Zeichen 4 Bit
value = value << 4; pbVideo++; //Weiterrücken
value = *pbVideo; //2. Zeichen 4 Bit
sprintf(str,"%x",(int)value);
fputs(str,pFile);
pbVideo++;

i++;
}
fclose(pFile);


Allerdings scheint diese auch nicht richtig zu funktionieren, weil das Ergebnis nur Quackel ist. Oder funktioniert sie richtig, und die Quellsamples sind nicht die richtigen? :|

Neomi
2006-12-20, 11:35:31
Hm, kompilieren geht, aber beim start stürzt es ab.

Wo denn genau? Was sagt der Debugger dazu?

pOut [Size2++] = pDigits [pData [i] >> 4];
pOut [Size2++] = pDigits [pData [i] & 15];

Verstehe ich nicht. Wie kommst du da an die Daten im Speicher auf den pData zeigt?

Mit i wird pData indiziert, so komme ich an die Daten. Die Daten (pData [i]) sind unsigned chars, die werden dann in zwei Gruppen zerlegt, erst die oberen 4 und dann die unteren 4 Bits. Daraus resultieren Zahlen von 0 bis 15, mit denen dann die Zeichentabelle indiziert wird, um die passende hexadezimale Repräsentation zu bekommen.

Allerdings scheint diese auch nicht richtig zu funktionieren, weil das Ergebnis nur Quackel ist. Oder funktioniert sie richtig, und die Quellsamples sind nicht die richtigen? :|

Der Typ BYTE belegt bereits 8 Bit, nicht 4. Du brauchst also keine Zusammensetzung von zwei Bytes. Wobei dein zweites Byte auch nicht mit dem ersten in irgendeiner Form zusammengesetzt wird, sondern den bisherigen Wert überschreibt. Und dann solltest du noch dringend die Formatierung von "%x" auf "%02x" ändern, weil du sonst die führenden Nullen und damit Daten verlierst.

Matrix316
2006-12-20, 13:20:37
Also meinst du es so?


BYTE *pbVideo;
pSample->GetPointer(&pbVideo);
BYTE* pbVideox = (BYTE*) malloc(cPTSf->samplesize);

BYTE value=NULL;
int i=0;
char str[3];

memcpy(pbVideox,pbVideo,cPTSf->samplesize);

FILE *pFile = fopen("c:\\values.txt","a+");
while (i<cPTSf->samplesize)
{
value = 0;
value = *pbVideox;
sprintf(str,"%02x",value);
fputs(str,pFile);
pbVideox++;

i++;
}
fclose(pFile);



PS.: Bei der ersten Version ist der Fehler nicht soo einfach zu debuggen. Die Funktion ist in einem DirectShow Transform Filter, und den Filter binde ich im Graph Edit in einen Filtergraphen ein. Da habe ich im Moment noch kein Programm zum Debuggen, sondern wenn ich Play drücke stürzt es ab mit Blablabla hat einen Fehler verursacht oder sowas. Ich schreibs noch mal genauer auf. ;)

Neomi
2006-12-20, 14:51:01
Also meinst du es so?

Ja, so schon eher. Aber warum setzt du value erst auf 0, wenn du direkt in der nächsten Anweisung den Wert wieder überschreibst? Und warum kopierst du erst von pbVideo nach pbVideox, wenn du eh nur lesend auf den Speicher zugreifst?

Matrix316
2006-12-20, 15:23:10
Ja, so schon eher. Aber warum setzt du value erst auf 0, wenn du direkt in der nächsten Anweisung den Wert wieder überschreibst? Und warum kopierst du erst von pbVideo nach pbVideox, wenn du eh nur lesend auf den Speicher zugreifst?

Hm, naja, das überschreiben mit 0 nur, damit nichts übrig bleibt. :rolleyes: ;)

Stimmt ist blödsinn das mit memcpy zu kopieren...aber was ist wenn die "samples" im Speicher nicht zusammenhängend drinstehen? Oder kann das nicht passieren?

EDIT: JUHU! Das ganze funktioniert sogar. :massa: :up: (y)

Neomi
2006-12-20, 15:49:06
Hm, naja, das überschreiben mit 0 nur, damit nichts übrig bleibt. :rolleyes: ;)

Warum denn :rolleyes:? Die Zuweisung ist einzig und allein davon abhängig, was rechts vom Zuweisungsoperator steht. Der vorherige Wert ist irrelevant.

Stimmt ist blödsinn das mit memcpy zu kopieren...aber was ist wenn die "samples" im Speicher nicht zusammenhängend drinstehen? Oder kann das nicht passieren?

Warum sollten die Samples nicht zusammenhängend im Speicher stehen, wenn du nur eine Startadresse und eine Buffergröße hast? Außerdem macht memcpy auch nichts anderes, als einfach nur einen zusammenhängenden Block zu kopieren.

Matrix316
2006-12-20, 15:53:10
Warum denn :rolleyes:? Die Zuweisung ist einzig und allein davon abhängig, was rechts vom Zuweisungsoperator steht. Der vorherige Wert ist irrelevant.



Warum sollten die Samples nicht zusammenhängend im Speicher stehen, wenn du nur eine Startadresse und eine Buffergröße hast? Außerdem macht memcpy auch nichts anderes, als einfach nur einen zusammenhängenden Block zu kopieren.

-Ok stimmt. Ist ja eine Zuweisung. War da etwas durcheinander, weil ich in meinen Funktionen auch mit bitweisen ODER hantiere und dort mehr aufgepasst werden muss.

-Das ist mir danach auch in den Sinn gekommen.

Ist jetzt aber auch egal weils FUNKTIONIERT! YES! :D