[gelöst für Plugins] DLLs sollen in ein Unterverzeichnis

Alles rund um die Programmierung mit Qt
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

Noch mal prinzipiell fuer mich, fuers verstaendniss ....

Diese " alle anderen (nicht-Qt-Plugin-) DLLs " sind das Plugins oder nur einfache Dlls ?

also nur funktionsbiblotheken, oder wirklich welche (mit nicht QT abhaengigen) eigenen Plugin mechanismuss.

Wenn es sich um einfache Dll's handelt, also solche die dan mit der importlib "zugelinkt" werden, ist die frage ob es wirklich "sinn" macht, die aus dem App verzeichniss rauszubekommen.

Zum hintergrund:
LoadLibrary("xxx.dll") verhaelt sich konform zu "sicherheitsstandard" von windows.
dabei ist gewahrleistet, dass wenn in der exe die dll angezogen wird, immer zuerst die aus dem verzeichniss der exe genommen wird, dann erst an anderen stellen gesucht wird. Das hat was mit sicherheit zu tun .... Wennn du zu deiner exe die dll auslieferst, und ins gleiche verzeichniss pappst, wird die dll immer passen.

Auf den pfad hasst du weniger einfluss ... und du solltest den auch nicht nur auf "..\bin" setzen, sondern um das erweitern. aber weisst du was vorher drinne steht ?
weiterhin kannst du per Regestry die suchreihenfolge umschalten .... ob die pathvariable vor den system verzeichnissen vorrang hat oder nicht ....

Das nur zur warnung, wenn die dll's wirklich nur von deinem prog gebraucht wird ... sollt es aber kein problem machen.

Alternative waere die dll nicht von der importlib anziehen zu lassen, sondern selber laden .... macht bissi mehr arbeit. dafuer kannst aber genau angeben wo die liegt dann.

statische Variablen in main.cpp müssten ja zuerst ausgewertet werden
nein, statisch lokale variablen werden eigentlich initialisiert, wenn sie das erste mal verwendet werden.

globale variablen werden vor dem main() initialisiert.
Dein problem ist aber, wenn die import libs das so machen, ist zwar definiert, das die variable in reihenfolge ihrer deklaration innerhalb einer datei initialisiert werden, aber nicht, in welcher reihenfolge die dateien "abgearbeitet" werden.

Sobald du die reihenfolge von den globalen Variablen in unterschiedlichen uebersetzungseinheiten beeinflussen willst, wird alles sehr compilerspezifisch.
Beim gcc (mingw) kenn ich mich damit ned soo genau aus ....

und bevor ich mit sowas anfangen wuerd (auch wenns beim VC relativ einfach ist) wuerd ich andere dinge versuchen .....

dadurch wird wohl die mingwm10.dll immer im Programmverzeichnis liegen müssen
Das ist die runtime fuer den gcc .... als entwickler kann man es sich da einfacher machen und sagen die mingw runtime muss installiert sein (ins system32 kopieren lassen) doof nur wenn user das programm nutzen sollen, die keine admin rechte haben .....
viel andere moeglichkeiten hasst da eh ned, da die runtime ziemlich rudimentaer ist, ohne der kannst eh gar nix manipulieren. Also entweder ins system32, oder neben die exe legen.

btw, das selbe problem haben VC entwickler auch .... die VC runtime braucht man auch..... aber dafuer liefert M$ nen eigenen installer, bzw bei den service packs wird das ding mit installiert .... alternativ kann man das ding auch anderswo hinpacken, und das ganze ueber nen manifest steuern.

Alternativ, statisch dazulinken ... kann man zumindest beim VC, damit kann man einfache konsolenproggies schreiben, die keinerlei dll anziehen .... beim gcc sollt das auch gehen. DIe exe wird dann nur ewtas groesser.

Alle anderen Dll's kannst austricksen, indem die abhaengigkeiten selber und damit deinen ganzen code in ne dll verlagerst, zu der dll die importbibs linken .... und bevor deine dll aufrufst (mit loadlibrary), deine PATH variable umsetzen ....

ne noch einfachere alternative, in deinem root verzeichniss eine exe, die auf ne andere exe in deinem /bin verzeichnis nen systemcall macht.
Musst aber auch dementsprechend absichern, weil der pure systemcall halt unsicher ist.
Geht natuerlich auch mit createProcess, dort kannst aber die Enviroment variablen sogar genau festlegen die mitgegeben werden ....

Ciao ....
FaS
Beiträge: 184
Registriert: 25. Mai 2006 19:48
Kontaktdaten:

Beitrag von FaS »

Diese " alle anderen (nicht-Qt-Plugin-) DLLs " sind das Plugins oder nur einfache Dlls ?
Einfache DLLs, mit echten Plugins hab ich mich noch nicht rumgeschlagen und ich kenn auch keine Bibliothek welche Plugins benutzt außer Qt [man muss sich das mal vorstellen, eine Bibliothek für Programmierer die sich im Endprodukt über Plugins lädt - bei Firefox z.B., Anwendungsspezifische Plugins, sowas ist akzeptabel aber nicht bei einer Bibliothek!] - und dann auch noch mit hard coded Unterverzeichnissen, ich könnt mich wirklich drüber aufregen, das ist der einzige Grund dieses Threads. Und wer schreibt schon Qt Plugins? Die paar (z.B. die 5 imageformats) kann man dann auch alle auf einmal ausliefern, da brauch man kein Plugin-System, und meist weiß man beim Programmieren eh was man will, ist für mich völliger Schwachsinn. Wenn man nach 10 Jahren ein weiteres Format unterstützen will kann man dann ja wohl auch ein neues Programm veröffentlichen, die neuen Qt-Plugins würden dann eh nicht mehr kompatibel mit der alten Version sein.
und du solltest den auch nicht nur auf "..\bin" setzen, sondern um das erweitern. aber weisst du was vorher drinne steht ?
Ja, getenv( "PATH" )
Alternative waere die dll nicht von der importlib anziehen zu lassen, sondern selber laden .... macht bissi mehr arbeit. dafuer kannst aber genau angeben wo die liegt dann.
Kann man denn eine stink normale Library benutzen, sprich das Programm kompilieren, wenn der Linker keine Implementierungen findet, da sie erst zur Laufzeit geladen werden? Der muss doch vorher schon die Einsprungspunkte kennen usw, kenn mich damit nicht aus. Aber wenn das so viel Arbeit macht, sprich für jede Bibliothek anders vorgegangen werden muss, ist das sowieso keine Lösung für mich.
Dein problem ist aber, wenn die import libs das so machen, ist zwar definiert, das die variable in reihenfolge ihrer deklaration innerhalb einer datei initialisiert werden, aber nicht, in welcher reihenfolge die dateien "abgearbeitet" werden.
PATH irgendwie auf bin zu setzen (sollte das funktionieren werd ich das erweitern statt alleine zuzuweisen..) finde ich immernoch die beste Lösung wenn das gehen sollte, allerding weiß der Linker welche libs benötigt sind, also wird er sie doch alle zusammen am Anfang laden, oder passiert das wirklich erst bei irgendwelchen globalen Variabeln (Ausgangspunkt:
Das hauptproblem bei dem auch von M$ benutzen prinzip mit der statischen BindeLib ist, das da das dynamische laden der dlls meist uber statische klassenmember (also quasi global) und damit vor dem main() erfolgt.
)? Jedenfalls hab ich mal in jeder *.cpp etwa folgendes oben reingemacht, Namen immer unterschiedlich:

Code: Alles auswählen

#include <cstdlib>
#include <iostream>
class TestInstance_ftp
{
  public:
    TestInstance_ftp();
};
TestInstance_ftp::TestInstance_ftp()
{
  std::cout << "TestInstance_ftp" << std::endl;
  putenv( "PATH=bin" );
}
static TestInstance_ftp testInstance_ftp;
Die Konstruktoren werden, zumind. bei mir, alle vor main() ausgeführt, der in der main selbst als letztes. Trotzdem schaut der nicht in "bin" nach sondern meckert dass eine DLL nicht gefunden wurde. In der Fehlermeldung steht ja auch "Die Anwendung konnte nicht gestartet werden, weil [...]", d.h. vielleicht will der die doch am Anfang laden unabhängig von irgendwelchen statischen membern?
[...]mingwm10.dll[...]
da die runtime ziemlich rudimentaer ist, ohne der kannst eh gar nix manipulieren.[...]
Alternativ, statisch dazulinken ... kann man zumindest beim VC, damit kann man einfache konsolenproggies schreiben, die keinerlei dll anziehen .... beim gcc sollt das auch gehen. DIe exe wird dann nur ewtas groesser.
16 wichtige Kilobyte.. Die lib*.a ist aber nicht mitgeliefert und ist wohl nicht sehr einfach, zumind. für mich, das Teil auf statisch zu ändern und manuell zu kompilieren usw.. Haben sich schon genug Leute damit rumgeschlagen und eine simple Lösung hab ich noch nicht gefunden, ist mir auch nicht so wichtig, Qt könnt ich auch statisch machen, is mir aber auch zu viel Arbeit, ich lasse lieber immer alle externen Dinge so wie sie sind. Qt 4.3.0 hat schon Fehler im build system wenn man über das Startmenü die debug libs kompilieren lässt, will mich mit sowas nicht rumschlagen und makefiles, configure-scripts etc. pp. sind eh nicht mein Ding.
Alle anderen Dll's kannst austricksen, indem die abhaengigkeiten selber und damit deinen ganzen code in ne dll verlagerst, zu der dll die importbibs linken .... und bevor deine dll aufrufst (mit loadlibrary), deine PATH variable umsetzen ....
Hmm gefällt mir nicht so und bekomm dadurch ja auch nicht alle DLLs weg.. Da wäre mir ein Starter-Programm lieber, ist ja im Prinzip fast dasselbe.
Nur müsste ich dann an Windows-APIs rumfummeln, igitt.. Aber akzeptabel, wüsste ich auch noch wie man es in Linux macht. Ich glaub die mächtige 16kb große mingwm10.dll braucht man nur wegen Qt, hab grad gelesen wenn man folgendes macht wird sie nicht mehr benötigt:
Entferne aus QTDIR\mkspecs\win32-g++\qmake.conf alle "-mthreads".
(Quelle) Aber das mit der Qt-Manipulation lass ich lieber. Und ein statisches Qt in allen Anwendungen ist auch nicht so schön (hab mehrere in meim Projekt), außerdem wenn, dann will ich schon alle DLLs wegbekommen und nicht nur ein paar.

Werd mir also vielleicht überlegen ein Starter-Programm zu schreiben wenn ich irgendwann Lust haben sollte zu schauen wie man ein Programm startet und die exe mit nem Icon versieht (bzw. meine .rc einbinde), ich hasse makefiles.. und dann noch eine Spezielversion für Linux.. Allerdings vergess ich die Icons da sowieso besser erstmal..
Oder du bekommst das mit dem PATH-im-Programm-ändern-bevor-die-libs-gesucht-werden hin ;-)
Oder ich ändere dieses nicht-von-Trolltech-Qt-Plugin (1 #define-Zeile) damit der nichtmehr im crypto-Unterverzeichnis nach Plugins sucht (allerdings wird der dann jede Bibliothek versuchen zu laden, glaub der prüft aber dabei ob die DLL für ihn ist, bin mir grad nicht sicher) und kompilier es neu, dann brauch ich kein bin-Verzeichnis mehr und dann können von mir aus auch alle DLLs ins Hauptverzeichnis - darf in Zukunft nur nicht vergessen dass ich das gemacht hab und muss hoffen dass ich niemals eingebaute Qt-Plugins brauche.
Antworten