Uwe K.
Manfred-Wörner-Straße 115
73037 Göppingen
0170/3106993
Uwe K.
Manfred-Wörner-Straße 115
73037 Göppingen
0170/3106993
Gerade habe ich folgendes Phänomen erlebt:
Beim Speichern eines GDI+-Bilds (Image– bzw. Bitmap-Klasse) bekam ich einen Statuscode 7 zurückgeliefert, was die Fehlermeldung „Win32Error“ bedeutet.
Also wie bei den meisten GDI+-Fehlermeldungen völlig ungenau und völlig an der wahren Ursache vorbei.
Da ich das ganze im Debugger laufen ließ und dieser bei First-Chance-Exceptions anhält, sah ich die genaue Stelle wo zum ersten Mal ein Fehler auftritt. Nämlich eine Zugriffsverletzung („Access violation“, 0x00000005) innerhalb von GDI+ an der folgenden Stelle im Aufrufstapel:

Bzw. als Textversion:
GdiPlus.dll!GpJpegEncoder::PushPixelData() + 0xa5 GdiPlus.dll!GpMemoryBitmap::PushIntoSink() + 0x14b GdiPlus.dll!GpMemoryBitmap::SaveToStream() + 0xa1 GdiPlus.dll!GpMemoryBitmap::SaveToFile() + 0x39 GdiPlus.dll!CopyOnWriteBitmap::DoSave() + 0x206 GdiPlus.dll!CopyOnWriteBitmap::SaveToFile() + 0x15 GdiPlus.dll!GpBitmap::SaveToFile() + 0x1f GdiPlus.dll!_GdipSaveImageToFile@16() + 0x5f zlzdiud.dll!Gdiplus::Image::Save() Zeile 140 + 0x18
Das Bild habe ich aus der Zwischenablage geholt (Zwischenablagenformat CF_DIB) und dann über die Funktion Bitmap::FromBITMAPINFO() ein Bitmap-Objekt daraus gemacht.
Nach einigen Tests habe ich herausgefunden, woran es lag:
Sobald ich den Speicher freigegeben hatte, der die Daten aus der Zwischenablage gespeichert hat (ein Instanz der MFC-Klasse CByteArray), schlug der Aufruf von Image::Save() mit oben genannter Fehlermeldung fehl; habe ich den Speicher erst nach dem Aufruf von Image::Save() freigegeben, verlief das Speichern erfolgreich.
Die Ursache ist also (wiedermal) wie bei den meisten GDI+-Routinen: Ich muß selbst dafür sorgen, daß ich den Speicher, aus dem ein ein Bitmap-Objekt erstellt wurde, lange genug reserviere, weil GDI+ sich das nicht selbst in interne Puffer kopiert.
Ist für ehrlich gesagt teilweise ggf. verständlich (Performance, Flexibilität), aber sehr unintuitiv (Komfort)!
Den Speicher für ein Bitmap-Objekt, das aus einem Aufruf via Bitmap::FromBITMAPINFO() (oder entsprechend anderer Funktionen) erstellt wurde, muß während der gesamten Lebensdauer des Bitmap-Objekts gültig sein und von der benutzenden Anwendung reserviert bleiben.

Sicher kennt Ihr den Spaß von Jugendlichen, das „Straßenlaternenaustreten“, also mit dem Fuß gegen den Kasten unten schaltet die Lampe für eine gewisse Zeit aus. Natürlich habt Ihr so was nie selber gemacht, nur vom Hören-Sagen. Ich natürlich nicht.
Folgendes beobachte ich seit ca. 5 Jahren in unregelmäßigen Abständen:
Wenn ich zu Fuß, per Fahrrad oder auch ab und an mit dem Auto an Straßenlaternen vorbeikomme, dann gehen die Lampen just in dem Moment aus, wenn ich daran vorbeikommen.
Also, es passiert nicht mit jeder Laterne und auch nicht jedes Mal wenn ich vorbeikomme, aber die Signifikanz ist deutlich zu hoch, um jedes Mal Zufall zu sein.
Glauben tut mir das natürlich keiner. Lachen mich alle aus, wie immer halt. Dem Jogi habe ich das während des Laufens mal erzählt, und natürlich hat er mich ausgelacht; jedoch genau 10 Sekunden später kamen wir an einer Laterne vorbei und die ging dann natürlich prompt aus. Der hat vielleicht dumm geschaut, der Jogi.
Anscheinend sind es nur bestimmte Arten von Laternen, die so auf mich reagieren. Ich glaube solche, die mit speziellen Lampen versehen sind (so mit Gasfüllung oder so) und solche, die eh’ schon ein bisschen einen Macken haben (z. B. Glühwendel kurz vor dem Durchbrennen). Bei solchen Laternen habe ich meist eine große Chance, dass eine davon ausgeht wenn ich vorbeikomme.
Also quasi “psychisch labile Laternen”.
Manchmal denke ich auch, dass mein Gemütszustand (gestresst, abgearbeitet, zornig, usw.) entsprechend sein muss, damit eine Lampe ausgeht. Aber das ist natürlich nur eine Vermutung.
Alles in allem also ein sehr seltsames Phänomen. Wenn Ihr mir auch nicht glaubt, so hoffe ich trotzdem, dass dieser Artikel zumindest etwas zu Eurer Erheiterung beigetragen hat.
Falls jemand ernsthafte Erklärungsversuche hat, bitte hier als Kommentar schreiben, ich bin sehr gespannt (und nein, “Uwe hat Halluzinationen” ist keine Erklärung).
2005-09-20, 5:15 Uhr, 2 °C, mit Rad an Laterne vor Eislinger Rathaus vorbei, Lampe aus, danach gleich wieder an.
Hartnäckigkeit zahlt sich oft aus: Heute habe ich ein Speicherleck (englisch „Memory leak“) in Zeta Producer korrigiert, das seit Version 5 drin war:
Beim Aufruf der Microsoft Scripting Engine habe ich beim Aufruf der Funktion IActiveScriptParse::ParseScriptText irrtümlicherweise CStringT::AllocSysString aufgerufen und den so angeforderten Speicher selbst nicht mehr freigegeben. Dies hätte ich jedoch machen müssen, was ich in der korrigierten Version nun mache.
Das hätte ich aber machen sollen! „RTFM“ hat Mario mir da gleich geantwortet als ich es ihm erzählt habe.
Hiermit also nochmals der ultimative Artikel wann wer für die Freigabe von Zeichenfolgen die mittels AllocSysString reserviert wurden verantwortlich ist: „Allocating and Releasing Memory for a BSTR (Visual C++ Concepts)„.
Auf einem Laptop (oder heißt das Notebook?) hatte ich seit kurzem folgendes Phänomen:
Sobald das Netzwerkkabel entfernt war (und WLAN deaktiviert), war der Windows-Explorer (auch die Shell selbst) mangels Geschwindigkeit praktisch unbenutzbar.
Allein das Startmenü-Öffnen war nur sehr langsam (im Minutenbereich) möglich. Ebenso dauerte es sehr lange, im Windows-Explorer einen Ordner anzuzeigen und dann zu einem anderen Ordner zu wechseln.
Mittels CommView habe ich herausgefunden, daß ständig Anfragen ins (nicht vorhandene) Netzwerk gesendet wurden.
So sahen die Netzwerkverbindungen des Laptops aus:

(Die betreffende Netzwerkkarte habe ich violett markiert).
Wenn nun das „Erweiterte TCP/IP-Einstellungen“-Dialogfenster dieser LAN-Verbindung angezeigt wurden, war die Option „NetBIOS-Einstellung“ auf den Wert „Standard“ gesetzt.
Sobald ich die Option auf den Wert „NetBIOS über TCP/IP deaktivieren“ aktiviert hatte, lief der Explorer wieder:

Was genau diese Option bewirkt hat sich mir trotz Recherche nicht so ganz erschlossen. Jedoch arbeiten nun alle Windows-Komponenten sowohl mit als auch ohne Netzwerkkabel zu meiner vollen Zufriedenheit.

Gestern habe ich versehentlich in eine Tabelle im Microsoft SQL Server doppelte Datensätze importiert.
Habe den Mario gefragt wie ich die wieder rausbekomme, seine übliche Antwort war natürlich „…geht mit Standard-SQL nicht…„.
Ha! Von wegen! Der Rainer hat genau 30 Sekunden gebraucht um den Artikel „Mehrfache Datensätze anzeigen und mit Ausnahme einer Zeile löschen“ zu finden.
Sieschd, Mario, es gooht doch! 🙂
Im verlinkten Artikel ist für mich die fast ganz unten stehende Abfrage meistens am passenden:
DELETE FROM tbl_Personen
WHERE [Personen-Id] NOT IN
(
SELECT MIN(X.[Personen-Id])
FROM tbl_Personen AS X
GROUP BY X.Nachname, X.Vorname, X.Geburtstag
)
Kurze Notiz: Die ehemaligen Redakteure der Zeitschriften „Happy Computer“ und „Power Play“, Boris Schneider und Heinrich Lenhardt haben beide ein Weblog.
Hach, das waren noch Zeiten, damals in der 80ern und 90ern….


Scheiße, ich glaube Elke hat doch Recht gehabt.
Alliterationen sind cool.
Heute waren Klaus und ich mal wieder klettern, wie jede Woche seit fast schon zwei Jahren. Diesmal wieder am Kahlenstein bei Geislingen. Anlaß genug, endlich mal ein paar Fotos zu schießen.



Es war schon halb neun, deshalb schon leicht dämmernd und deshalb war auch das Licht etwas „ungewöhnlich“.