Gegen Internetzensur
Stoppt die Vorratsdatenspeicherung! Jetzt klicken & handeln!Willst du auch bei der Aktion teilnehmen? Hier findest du alle relevanten Infos und Materialien:
  • Flickr Photos

    www.flickr.com
7. Nov
Mit

Gandalf, libGD and all the like

Noch ein paar Stunden und ich laufe Amok. Zuerst der Ärger darüber, dass es zwar tausende Buildsysteme gibt, die alle behaupten, sie wären toll und portabel, dann aber nicht unter Windows laufen; Später der Ärger dass auch wirklich bei jedem Pupsprojekt extensiver Gebrauch eines anderen Buildsystemes gemacht wird (um die tausend vollzukriegen, denke ich mal) und dann zuletzt der Ärger, dass unter Windows überhaupt nichts geht.

Was wird das? Kompiliere ich die Anwendung mit cdecl-Aufrufkonvention funktioniert GD, aber gandalf nicht. Nutze ich stdcall ist es genau anders herum! Is doch zum Kotzen, ich will doch nur Bilder auswerten!

(Mein aktueller Spaß besteht darin, die Grafikbibliothek Gandalf und die gut bekannte Bibliothek GD in ein- und derselben Anwendung zum Arbeiten zu bewegen. Aus Gründen der Faulheit habe ich mich entschlossen, in C++ zu arbeiten und aus Gründen der Portierbarkeit dafür, dass es keine Windows-Anwendung ist)

Nachtrag:
Wer lesen kann, ist klar im Vorteil: Auszug aus der libGD-FAQ:

Microsoft Visual C++: If you want to use gdImageCreateFromPng, gdImagePng, and other functions that take a FILE *, you MUST use Visual C++ 6.0 or earlier and you MUST link with the “multithreaded DLL” runtime library option. If you wish to use the .NET compiler, read the “Borland C++” section for an alternative method.

Ich bin der Lösung des Problems entsprechend beigekommen, wenn auch nicht exakt nach Vorgabe der FAQ. Via CMake werden die Solutions für Visual Studio erstellt, dort wird die ignorierte Library aus dem Projekt entfernt, um Bindungsprobleme mit libpng zu beheben. Im eigentlichen Programm wird später schlichtweg gegen bgd.lib gelinkt und der Header gd.h eingebunden (dieser setzt sich selbst automatisch extern "C", wenn C++ entdeckt wird).
Der einzige Unterschied ist nun, dass man anstelle der Funktionen, die einen FILE-Pointer erwarten solche wählt, die mit einem einfachen Speicherpuffer arbeiten. Beispiel:

  1. gdImagePtr im = gdImageCreate(600, 200);
  2.        
  3. int black = gdImageColorAllocate(im, 0, 0, 0);
  4. int white = gdImageColorAllocate(im, 255, 255, 255);
  5.  
  6. gdImageFill(im, 0, 0, black);
  7. gdImageRectangle(im, 30, 30, 570, 170, white);
  8.  
  9. // write image
  10. FILE* pngout = fopen("output.png", "wb");
  11.  
  12. // Workaround für Crashes in: gdImagePng(im, pngout);
  13.  
  14.         // PNG-Daten puffern
  15.         int size;
  16.         char* data = (char*)gdImagePngPtr(im, &size);
  17.  
  18.         // in die Datei schreiben
  19.         fwrite(data, sizeof(char), size, pngout);
  20.  
  21.         // Daten freigeben
  22.         gdFree(data);
  23.  
  24. // Datei schließen
  25. fclose(pngout);
  26.  
  27. // close gd image
  28. gdImageDestroy(im);

Weitere Beispiele in der FAQ. Whatever.

Die Kommentarfunktion ist geschlossen.