Archiv verlassen und diese Seite im Standarddesign anzeigen : c++: lib und dll mit VC2005
Ka55i0peia
27-04-2009, 16:48
Hallo Leute,
versuche gerade meine erste *.dll in ein Projekt mit einzubinden.
Das geht soweit mit
#include "shapelib/shapefil.h"
#pragma comment (lib,"shapelib/shapelib.lib")
So wie ich das jetzt verstanden habe, verlinkt die *.lib das dll-file automatisch und ist zugleich ein Index für die im dll-file enthaltenen Funktionen (!?)
(->Wenn falsch bitte berichtigen.)
Nun zur Frage:
Damit das dll-file verlinkt wird, muss es sich im gleichen Ordner wie das executeable-file (*.exe) befinden -> sonst: Fehlermeldung zur Laufzeit. Damit die Ornderstruktur in meinem Programm schlüsslig bleibt:
Wie kann ich diesen Pfad ändern?
Wunschstruktur:
#
|- start.exe
*- shapelib/
|- shapelib.lib
*- shapelib.dll
Hat jmd. eine Idee?
Nette Grüße,
derJan
Soweit ich weiß muss man unter Windows DLLs registrieren (wenn man sie nicht in das selbe Verz. wie die .exe gibt). Der Befehl war irgendwas wie: regsvr32 shapelib.dll
Bin mir aber nicht mehr sicher, hab schon lange kein Windows mehr verwendet.
Yonibear
29-04-2009, 09:47
Unter Windows kannst du den Suchpfad der DLLs nicht mit der linkenden Anwendung angeben. Eine Möglichkeit wäre die PATH-Variable anzupassen, aber das ist relativ hässlich, weil die dann eben global gesetzt werden müsste.
Die einzige Möglichkeit, DLLs ohne Änderungen an der Systemkonfiguration aus Unterverzeichnissen zu laden, ist sie dynamisch zur Laufzeit mit LoadLibrary etc. einzubinden. Das macht man aber eigentlich nur für Plugin-Mechanismen, wo man die verwendeten DLLs zur Compiletime nicht kennt, für normale Libs macht das nicht wirklich Spaß, da du dann alle Funktionen über Funktionspointer einbinden musst.
Ka55i0peia
29-04-2009, 10:51
Die einzige Möglichkeit, DLLs ohne Änderungen an der Systemkonfiguration aus Unterverzeichnissen zu laden, ist sie dynamisch zur Laufzeit mit LoadLibrary etc. einzubinden.
Okay, das hatte ich auch mal gesehen, ist aber sehr umständlich -zumal jede funktion registriert werden muss.
regsvr32 shapelib.dll
Kommt die Meldung: "c:\shapelib.dll wurde geladen, aber der DllRegister-Servereingangspunkt wurde ncht gefunden. Diese Datei kann nicht registreirt werden."
Öhm, naja...
Dringlich ist das Problem nicht, aber sollte jmd. ne Lösung parat haben, würde ich mich freuen.
Grüße,
derJan
Seit "neuesten" (wie gesagt, hab schon lange nimmer Windows verwendet) gibts ja auch so Manifest Datein die irgendwie mit den exe Datein verbunden oder zusätzlich dazu ausgeliefert werden. Du kannst ja mal nachrecherchieren ob sich damit was machen lässt. In etwa den "LD_LIBRARY_PATH" (so heißt's unter Linux, musst schaun wie das unter Windows heißt) für das Programm setzen.
Mit den manifests kenn ich mich ned aus, wir arbeiten hier noch mit den "Klassichen" Methoden ...
Soweit ich weiß muss man unter Windows DLLs registrieren
Definitiv nicht !
Was man registrieren muss sind COM-Komponenten. Diese tragen Ihren Komponentennamen ihre GUUID usw in die Registry, und jeder Client der sie nutzen will, sucht in der reg nach dem key, findet den eintrag, und laed die richtige dll dann, egal wo sie steht.
Wie gesagt nur bei COM Komponenten.
Dlls ohne COM iss das vollkommen schnuppe.
Die Importlib, die beim erstellen mit erzeugst, macht dir nix anderes, als die dll noch vor der main zu laden, und zwar mit nem loadlibrary("DllNameOhnePfad") ...
Weiterhin werden die exportierten funktionen neu deklariert und auf die mit GetProcAdress ermittelten einsprungpunkte umgeleitet.
DU sparst also nur den allgemeinen loadlibrary aufruf, sowie das GetProcAdress fuer jede exportierte funktion.
Wird kein Pfad bei loadlibrary angegeben, wird die Dll standardmaessig in reihenfolge an folgenden Orten gesucht:
- Das verzeichniss des gestarteten binaries (achtung, Hat nix mit currentDir zu tun !)
- Alle Pfade in der PATH Umgebungsvariable
- Alle Systemverzeichnisse (system, system32)
(iss die standardeinstellung, die liste kann man in grenzen aendern ueber die sicherheitspolicies, in der registry)
Bei Plugins, die "nur" von bestimmten verzeichnissen geladen werden sollen, sollt man direct mit vollen Pfad und loadlibrary die dlls laden.
Ausserdem will man das laden meist kontrollieren und zu bestimmten zeitpunkten haben, weswegen die man soweiso ned mit der Importlib laed.
WIr laden aber andere dlls auch haendisch mit loadlibrary, soviel komfort bringt die lib auch ned ....
Was genau exportiert wird aus der dll, steht in der sogenannten Exporttable im Kopf der dll .... (kann man sich mit dem dependencywalker anschauen)
Diese Tabelle wird entweder ueber den Praeprozessor mit den __declspec( dllexport ) Keywords erzeugt (MS spezifisch) oder ueber eine expliziete definitionsdatei (.def),
Nur fuer die in der Tabelle definierten funktionen kann GetProcAdress ne einsprungadresse finden ....
Ciao ...
Ka55i0peia
08-05-2009, 09:11
Nach längerer pause (sorry).
Ersteinmal: Danke für deine/eure Antwort(en).
@RHBaum:
So wie ich deinen Eintrag verstanden habe, würde theoretisch sowas wie
int main(void)
{
LoadLibrary( dll_name )
...
FreeLibrary()
}
reichen!?
Folgender Code linkt aber immernochnet die Bibliothek aus dem gewollten Ordner:
string pfad = "shapelib/shapelib.dll";
HMODULE hMod = LoadLibrary( (LPCWSTR)pfad.c_str() );
Grüße,
derJan.
PS: Derzeit begnüge ich mich damit, dass die dll's einfach im Ordner des binaries liegen. Klappt zwar, schöner ist es aber halt, wenn diese in unterverzeichnissen im projektordner verschwinden können.
1. Versuche \\ statt /
2. Ist der Pfad relativ zu dem Verzeichnis aus dem du's ausführst? Versuche besser einen absoluten Pfad zu ermitteln.
Ka55i0peia
09-05-2009, 10:30
Bringt keine Erfolge.
Bricht dennoch mit der Meldung ab, dass er die dl nicht finden kann.
Auch wenn ich in VS2005 den pfad wo die dll liegt mit angebe
(Menu:Project->Preferences->Common Properties->Additional Reference Search Path)
kein Erfolg!?
Glaub ich gebs langsam auf und begnüge mich damit, dass die dlls im gleichen Ordner wie das Binary liegt..
Yonibear
09-05-2009, 20:09
Die DLL mit LoadLibrary zu laden reicht eben nicht. Du musst komplett auf das #pragma und die .lib verzichten, und ausschließlich Funktionspointer verwenden, die du mit GetProcAddress aus der Library zuweist.
Powered by vBulletin® Version 4.2.5 Copyright ©2025 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.