Schönen guten "Morgen",
Ich verzweifel so langsam am meinem Code. Ich möchte ein Imagebuffer
auslesen von einer Kamera. Es liegen im Buffer mehrere Bilder (176x144
Pixel, 8bit Grausstufen) hintereinander. Wenn ich meine For-Schleife nur
bis 25344 laufen lasse (sprich nur ein Bild auslesen möchte) klappt dies
einwandfrei. Wenn ich jedoch wie unten angegeben zwei Bilder
gleichzeitig auslesen möchte, kriege ich ein Fehler:
Eine Ausnahme (erste Chance) bei 0x008a1bae in Test4.exe: 0xC0000005:
Zugriffsverletzung beim Lesen an Position 0x02b98000.
Unbehandelte Ausnahme bei 0x008a1bae in Test4.exe: 0xC0000005:
Zugriffsverletzung beim Lesen an Position 0x02b98000.
Das Programm "[2980] Test4.exe: Systemeigen" wurde mit Code -1073741819
(0xc0000005) beendet.
Der Fehler taucht in der Zeile "buffer[j] = *(imagebuffer+j);" auf, wenn
ich die For-Schleife zum 27497sten Mal durchlaufen möchte.
Habe lange Zeit nicht in C++ programmiert. Habe ich etwas übersehen?
Anbei die "fehlerhafte" Codestelle.
MfG
Ich programmiere zur Zeit eine 3D-Kamera die zwei Bilder im Buffer
hinterlegt, einmal ein Graustufen Bild und einmal die
Tiefeninformationen.
Laut Datenblatt sind zwei Images dort mit 8bit Auflösung gespeichert.
Den Zeiger "imagebuffer" erhalte ich von einer Funktion, die in dem
"Framework" der Kamera enthalten war.
Die Schleife bricht immer an der selben Stelle ab. Zu dem Zeitpunkt kann
das zweite Bild aber noch "lange" nicht ausgelesen sein.
Typ von imagebuffer:
unsigned char* imagebuffer
MfG
Leider fehlt ein wichtiger Teil des Quelltextes.
1/ Ist imagebuffer vom Typ unsigned char *?
2/ Wie groß ist der Puffer, auf den imagebuffer zeigt?
Ich vermute kleiner als 50688 * sizeof(unsigned char).
Das lässt annehmen, daß "imagebuffer" doch nicht auf so viel Speicher
zeigt, wie Du annimmst. Hast Du Dir mal im Debugger den Inhalt von
imagebuffer als Hexdump angesehen?
Philipp G. schrieb:> Laut Datenblatt sind zwei Images dort mit 8bit Auflösung gespeichert.> Den Zeiger "imagebuffer" erhalte ich von einer Funktion, die in dem> "Framework" der Kamera enthalten war.
Wie sieht die Funktion aus?
> Typ von imagebuffer:> unsigned char* imagebuffer
Zeig mal die Codestelle, wo du dann an den Pointerwert kommst.
An die eigentliche Funktion komme ich nicht herran.
Die Referenz sagt lediglich:
BGAPI_RESULT BGAPI::Image::get ( unsigned char ** imagebuffer )
Function category: Retrieve image information. Use this function to get
a pointer to the begin of image data.
Parameters: 'imagebuffer' (OUT) Pointer to begin of image data.
Return values: 'BGAPI_RESULT_OK' No error.
Könnte mir jemand schonmal sagen wie ich im Debugmodus den kompletten
Wertebereich des imagebuffer einsehen kann (in hex).
Philipp G. schrieb:> Könnte mir jemand schonmal sagen wie ich im Debugmodus den kompletten> Wertebereich des imagebuffer einsehen kann (in hex).
Dazu gibt es im Menü "Debug" den Unterpunkt "Windows -> Memory".
Mir wurde gesagt, dass sich diese "Callback" funktion wie eine Art ISR
(Interrupt) verhält. Sobald Informationen vorhanden sind, wird in diese
Funktion gesprungen und Zeiger auf die Speicheradresse zugeordnet.
Philipp G. schrieb:> Mir wurde gesagt, dass sich diese "Callback" funktion wie eine Art ISR> (Interrupt) verhält. Sobald Informationen vorhanden sind, wird in diese> Funktion gesprungen und Zeiger auf die Speicheradresse zugeordnet.
Yep. Das sieht erst mal richtig aus.
Die Frage ist allerdings, wie lange dieser Buffer (und damit der
Pointerwert den du dir holst) Gültigkeit hat. Im schlimmsten Fall müsste
man von den Daten in der Callback Funktion eine Kopie erzeugen. Das
würde sich sogar anbieten, da du nur in der Callback Funktion sicher
sein kannst, dass noch niemand die Bilddaten überschrieben hat (weil die
Kamera bereits am nächsten Bild arbeitet) (*)
Das andere, wobei es mir die Nackenhaare immer ein wenig aufstellt, sind
magische Konstanten, wie zb deine 50688
(*) Edit:
Es sei denn natürlich, die Doku sagt etwas anderes.
Nun ja, es ist ja fast schon einleuchtend, dass die Bilddaten nur fürs
Callback gültig sind. Sonst würd die Kiste ja leaken ohne Ende. Aber wie
Karl Heinz schon sagte: Wenn in der Doku was Anderes steht, ist das
nunmal so. Aber ich würd davon ausgehen, dass du wirklich eine Kopie
anlegen musst.
Ich habe mir grad mal den Speicher angeschaut (wie mir von Rufus t.
Firefly geraten wurde).
Grob gesagt, mitten im 2ten Bild stehen dort nurnoch Fragezeichen
anstatt von Hexadezimalen Werten. Somit wurde der Speicher dort
anscheinend noch nicht beschrieben.
Ich gehe davon aus,dass der Speicher bzw. der Pointer solange gültig ist
bis ich mir ein neues Bild erzeugen lasse. Im Moment erstelle ich pro
Programmablauf nur ein Bild (aber 2x144x176 Informationen mit jeweils
8bit).
MfG
Danke schonmal für eure Mühen/Geduld
@Nico22: Was meinst du mit Kopie?
Philipp G. schrieb:> Ich gehe davon aus,dass der Speicher bzw. der Pointer solange gültig ist> bis ich mir ein neues Bild erzeugen lasse.
Ganz wichtig:
Steht das so in der Doku oder ist das eine Annahme von dir?
Hintergrund: Einen Pointer auf irgendwelche Daten rausrücken, ist für
eine Lib immer ein Hazardspiel, weil sie nicht kontrollieren kann, wie
lange sich der Aufrufer den Pointer aufhebt.
> @Nico22: Was meinst du mit Kopie?
Na Kopie der Daten!
Der Callback wird aufgerufen, innerhalb der Callback Funktion holst du
dir den Pointerwert, allokierst selber Speicher und machst eine Kopie
der Bilddaten. Bei return aus dem Callback kann die Library mit ihrem
eigenen Buffer machen was sie will, interessiert keinen mehr, du hast
dir ja die Daten bereits geholt.
Philipp G. schrieb:> Grob gesagt, mitten im 2ten Bild stehen dort nurnoch Fragezeichen> anstatt von Hexadezimalen Werten. Somit wurde der Speicher dort> anscheinend noch nicht beschrieben.
Nicht nur nicht beschrieben, sondern gar nicht vom Prozess vom
Betriebssystem angefordert.
Zugriffe auf solche Speicherbereiche führen zu einer Exception, und
deren Resultat ist Deine Zugriffsverletzung.
Bietet denn Deine Kamera-Library keine Funktion, die Aussagen darüber
trifft, wie groß der Speicherbereich ist, auf den
pImage->get(&imagebuffer);
einen Pointer liefert?
Ersteinmal zu "Karl heinz Buchegger":
Ich gehe von der Annahme aus, denn die Doku ist eher supoptimal
geschrieben, da die Kamera noch ziemlich neu ist.
Das mit der Kopie werde ich gleich mal ausprobieren!
Und zu " Rufus t. Firefly":
Leider gibt es solch eine Funktion nicht. Hätte ich auch gerne gahebt
:-D
Würde ich erstmal prüfen ob das speichern überhaupt geklappt hat. Ist
den
imagebuffer überhaupt groß genug um alle Daten aufzunehmen? Den Spciher
mußt du so wie ich das sehe nämlich selbst anlegen, am besten mit nem
AutoPtr oder so...
Tja, dann ist möglicherweise Deine Annahme, daß da zwei Bilder
hintereinander im Puffer stehen, schlicht und einfach nicht korrekt.
Da die tolle Library anscheinend keine Informationen über in diesem
Puffer befindliche Daten zur Verfügung stellt, wirst Du die Bilder
einzeln anfassen müssen.
Du könntest mal -- rein Interessehalber -- die Headerdatei posten, in
der
BGAPI::Image
deklariert ist.
Rufus t. Firefly schrieb:> Tja, dann ist möglicherweise Deine Annahme, daß da zwei Bilder> hintereinander im Puffer stehen, schlicht und einfach nicht korrekt.
Es wäre auch denkbar das die Funktion get einfach zweimal hintereinander
aufgerufen werden muss und jedesmal je ein Bild liefert.
Habe jetzt probiert, dass bei jedem Öffnen der Callback funktion, der
buffer in ein anderes Array gespeichert wird.
Aber ich lese lediglich das erste Bild aus, weil ich dachte, dass
vielleicht der Buffer für die beiden Bilder derselbe ist.
Ist leider auch fehlgeschlagen. Habe nun in beiden Arrays ein
Graustufenbild.
Zu dem Aufbau der Callback-Funktion:
Die habe ich angepasst. Die Beispiele die mitgeliefert wurde waren nur
für normale Kameras (ohne Tiefeninformation).
MfG
PS: öfter die get-Funktion aufrufen, funktioniert auch nicht.
Aus den Funktionen werde ich nicht ganz schlau.
BGAPI_RESULT BGAPI::Image::getBufferLength ( int * maxlength,
int * minlength,
int * currentlength
)
Function category: Retrieve image information. Use this function to get
the current buffer length in bytes.
Parameters:
'maxlength' (OUT) Maximum buffer length of all existing images formats
of the connected camera.
'minlength' (OUT) Minimum necessary buffer length for the image. This
buffer length based on the current image format settings of the
connected camera and is byte exactly calculated.
'currentlength' (OUT) Current used buffer length.
Return values:
'BGAPI_RESULT_OK' No error.
BGAPI_RESULT BGAPI::Image::getImageLength ( int * length )
Function category: Retrieve image information. Use this function to get
the image length in bytes.
Parameters:
'length' (OUT) Maximum buffer length.
Return values:
'BGAPI_RESULT_OK' No error.
Default ist der kombinierte Modus! Und verstellt habe ich eigentlich
nichts.
MfG