"Christmas - the time to fix the computers of your loved ones" « Lord Wyrm

Erstellen einer dll (PHP-Extension) in Visual C++ 2008

jives 08.09.2008 - 21:44 1004 4
Posts

jives

And the science gets done
Avatar
Registered: Sep 2001
Location: Baden
Posts: 3548
Ich hätte eine Frage, zu der ich leider auch nach intensiver Suche nichts finden konnte, und hoffe ihr könnt mir einen Tipp geben.

Vorgeschichte
Wer diesen Thread verfolgt hat, weiß schon worum es geht ;)
Kurz umrissen möchte ich eine PHP-Extension für PHP 5.2.6 unter IIS 6.x und Windows Server 2003 schreiben. Meine Testumgebung läuft auf IIS 5.1 unter Windows XP. Die Extension soll hauptsächlich eine Berkeley DB verwalten.

Symptome
Vorneweg: Ich benutze VC++ 2008 Express, weil ich es nicht geschafft habe, meine Extension mit MinGW zu kompilieren (die PHP-Entwickler scheinen hier einfach ausschließlich auf VC++ gesetzt zu haben). Deswegen bewege ich mich hier etwas auf Neuland.

Nach stundenlangen Spielereien bin ich draufgekommen, dass meine Extension funktioniert, so lange ich bei den Projekteigenschaften unter C/C++ -> Code Generation -> Runtime Library "Multi-threaded" bzw. "Multi-threaded Debug" auswähle. Wähle ich "Multi-threaded DLL" aus kompiliert VC zwar brav, aber PHP bzw. Windows beschwert sich beim Laden, dass "[...] die Anwendungskonfiguration nicht korrekt ist. [...]".

Nachdem ich nun Berkeley DB benutzen will, hab ich mir den Sourcecode gesaugt und mit VC++ kompiliert. Das ging problemlos, da das entsprechende Projektfile im Source beiliegt und komplett vorkonfiguriert ist. Das Linken meiner Extension gegen die resultierende lib/dll funktioniert auch - nur PHP weigert sich, die BDB dll zu laden. Die Fehlermeldung ist die gleiche wie oben. Abhilfe schafft ein Umstellen der Berkeley DB-Projektoptionen von "Multi-threaded DLL" auf "Multi-threaded" (und einem darauf folgenden Rebuild) - und das macht mich natürlich schon stutzig.

Frage
Ist das so gewollt, oder hab ich beim Konfigurieren der Optionen etwas verhunzt? Sollte ich für die Erstellung einer dll nicht eigentlich "Multi-threaded DLL" auswählen müssen? Ehrlich gesagt habe ich es bisher nicht geschafft zu kapieren, was diese Option überhaupt genau macht - außer, dass es hier ums Linken gegen eine der MSCV*.dlls geht. Aber was das für die resultierende Applikation bedeutet, weiß ich leider nicht.

Ich hoffe ihr könnt meine Verwirrung ein bisschen aufklären - tia jedenfalls :)
Bearbeitet von jives am 08.09.2008, 21:49

that

Moderator
Hoffnungsloser Optimist
Avatar
Registered: Mar 2000
Location: MeidLing
Posts: 11338
Also, MSVC hat 6 Runtimes...

Je 3 sind für Debugging und 3 für Releaseversionen. Erstere haben z.B. eine andere Speicherverwaltung, die Speicher initialisiert, überschriebene Bereiche checkt, beim Freigeben überschreibt und am Ende Leaks findet.

Die 3 Varianten sind:
- Single-threaded
- Multi-threaded
- Multi-threaded DLL

Die erste davon vergessen wir gleich, wir haben 2008. Bleiben noch die ominösen 2 übrig. Die "Multi-threaded" Runtime wird statisch zu deiner DLL gelinkt, die "DLL"-Version ist in einer eigenen DLL und wird von allen DLLs und dem EXE im selben Prozess benutzt.

Folgen der Verwendung der statischen Runtime: Jede DLL hat ihre eigene Kopie der Runtime, damit auch ihren eigenen Heap, Locale, und anderen "globalen" Zustand. Du kannst also nicht Objekte in einer DLL anlegen und in einer anderen freigeben, d.h. auch zwischen den DLLs kannst du keine C++-Objekte übergeben.

Folgen der Verwendung der DLL-Runtime: Es gibt nur eine Kopie der C-Runtime im Prozess. Alles läuft auf dem selben Heap. Das entspricht eher der Unix-Umgebung, kann aber zu Versionskonflikten führen (falls du DLLs in einem Prozess mischst, die z.B. mit unterschiedlichen Compilerversionen gebaut wurden).

mat

Administrator
Legends never die
Avatar
Registered: Aug 2003
Location: nö
Posts: 25422
Zitat von jives
"[...] die Anwendungskonfiguration nicht korrekt ist. [...]".
Deutet auf eine falsche (oder keine) Version der CRT-DLLs hin. Um den Fehler genau herauszufinden, kannst du die DLLs in das ausführende Verzeichnis legen (also in den Apache-Folder bzw. beim IIS.. mhm.. keine Ahnung :p), damit die alternativen Orte (x:\Windows\System32 usw.) ausgeschlossen werden können.

Edit: Installier mal vorab das passende VC-Redist-Package.

jives

And the science gets done
Avatar
Registered: Sep 2001
Location: Baden
Posts: 3548
@that
Danke für die gute Erklärung :)

Ich hab das glaube ich in der Zwischenzeit halbwegs behirnt, nachdem ich heute seit Stunden versuche die oben beschriebene Fehlermeldung weg zu bekommen und mich deshalb nochmal eingelesen hab.

@mat
Genau das ist das Problem - ich hab das heute erst vor ein paar Minuten kapiert und mich eingelesen.
Mir kommt das Ganze (Manifests, SxS, ...) doch sehr kompliziert vor - ist das eine MS-Spinnerei oder bin ich auf anderen Systemen bisher nur von sowas verschont geblieben?

Die entsprechenden DLLs in die Verzeichnisse zu kopieren war nicht die Lösung, das hab ich vorher schon probiert. Dafür aber die Installation des Redist-Paketes :)
Zum Glück hab ich vorher stundenlang mit Manifests und deren embedden herumgespielt - und dabei ist die Lösung zumindest scheinbar so einfach ;)

Muss das Redist-Paket jeder Benutzer eigens installieren, oder ist eine Installation systemweit?

mat

Administrator
Legends never die
Avatar
Registered: Aug 2003
Location: nö
Posts: 25422
Systemweit afaik.
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz