Tutorial für dlls
-
Hallo
Also ich habe mich schon reichlich über google und auch über die Suchfunktion hier bemüht, aber irgendwie nichts gefunden was mir weiterhilft.
Ich suche einfach nur ein Tutorial oder einer Anleitung, wie ich eine von mir geschriebene dll in mein C++ Projekt einbinde. Hab das früher schonmal hinbekommen, bin aber jetzt etwas eingestaubt.
(gab ja mehrere Möglichkeiten mein ich. Ich suche die, wo man die dll über Projekt->Einstellungen bekannt gegeben hat und dann ein einfaches #include "header.h" ausreichte. Oder so ähnlich wars mein ich)Außerdem hab ich bei der Release-Version meiner dll nur eine *.dll-Datei erhalten. Reicht diese Datei aus? Bin mir nicht sicher, ob man auch noch die header-Datei selber und/oder eine *.lib Datei benötigte.
Falls es hier schon irgendwo in der faq erklärt ist, dann bitte ich um Verzeihung. Hab leider nichts dergleichen gefunden.
-
Also wenn ichs jetzt richtig gelesen hab, brauche ich wohl die *.lib Datei.
Allerdings hab ich keine Ahnung wie man die erstellt, bzw warum die beim kompilieren nicht erzeugt wird.Unter Projekt->Einstellungen gibts zwar eine Einstellung "keine LIB erzeugen", die ist allerdings weder bei Debug noch bei der Release-Version aktiviert und trotzdem erhalte ich nie eine *.lib Datei.
-
Du erhältst dann keine .lib Datei wenn deine DLL nix exportiert.
Schreib in den Code mal (auf File-Scope) einfach
__declspec(dllexport) int test234 = 0;rein, und compilier das ganze nochmal. Dann solltest du eine .lib haben.
Achja: was exportiert wird kann man leicht mit www.dependencywalker.com angucken.
-
ok, jetzt klappts.
Und wie baue ich die dll jetzt in mein neues Projekt ein?
Also soweit bin ich bis jetzt gekommen:
1)ich habe die *.dll *.lib und .h Datei in den Ordner meines Projekts kopiert.
2)IM neuen Projekt binde ich die Headerdatei mittels #include ".h" ein
3)Unter Projekt->Einstellungen Register Linker Feld Objekt/Bibliothek-Module gebe ich die *.lib bekannt (sowohl bei Debug als auch bei Release)Fehlt noch was? Bis jetzt tritt beim kompilieren zwar kein Fehler auf, er erstellt aber trotz 0Fehler, 0Warnungen Meldung keine *.exe Datei.
//edit: Wenn ich versuche die Datei direkt auszuführen, dann kommt erst eine Abfrage ob die Datei neu erstellt werden soll und danach die Fehlermeldung "Datei kann nicht ausgeführt werden".

//edit2: Ich habs jetzt soweit, dass ich die dll einbinden konnte. Dafür meldet er mir 2 nicht aufgelöste externe Symbole.
(Die dll besteht zum großen Teil aus einer Klasse, der Konstruktor ruft 2 private Funktionen auf. Und dieser Aufruf führt anscheinend zu den Fehlern)dll-Header: class Klasse{ private: void FunktionA(); void FunktionB(); public: Klasse(){FunktionA; FunktionB;}; }; im Projekt: #include "dll.h" void main(){ Klasse A; };so sieht das ganze aus. Und als Fehlermeldung kommen dann
"nichtaufgelöstes externes Symbol ... FunktionA"
"nichtaufgelöstes externes Symbol ... FunktionB"
-
So, meine Header-Datei der dll sieht jetzt wie folgt aus:
#include <fstream> #include <string.h> using namespace std; class __declspec(dllexport) sdcObj { private: string filename; string** fileContent; int maxRow; int maxCol; void LoadSdcFile(); void CloseSdcFile(); string readCell(int row, int column); int getKeyRow(string keyword); int getKeyCol(string keyword); void setCell(int row, int column, string content); void setCell(int row, int column, float content); public: sdcObj(string Obj_filename){ filename = Obj_filename; LoadSdcFile();}; ~sdcObj(){CloseSdcFile();}; float fGetCellContent(string key1, string key2); string sGetCellContent(string key1, string key2); void SaveSdcFile(); void SaveSdcFileAs(string Obj_filename); };Beim einbinden in das Projekt entsteht dann folgende Warnung:
c:\test\sdcclass.h(7) : warning C4251: 'filename' : class 'std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' benoetigt eine DLL-Schnittstelle, die von Clients von class 'sdcObj' verwendet wirdDabei sieht die Projekt-Datei im Moment wie folgt aus:
#include <iostream.h> #include "sdcClass.h" void main(){ cout << "test" << endl; sdcObj mySdc("misc.txt"); cout << "test" << mySdc.sGetCellContent("key1","key2").c_str() << "test" << endl; };Wenn ich das Programm trotz der Warnung ausführe dann erscheint nur die erste Ausgabe "test", zu der zweiten kommt er erst garnicht mehr. Also scheint er mit dem Konstruktor irgend ein Problem zu haben.
-
vlt. hilft Dir ja dieser Link ein wenig weiter:
http://www.gamedev.net/reference/articles/article928.asp
-
hilft nicht so wirklich weiter. Treten immernoch die gleichen Fehler auf, und der Code in dem Link macht so ziemlich das Gleiche, was meiner auch macht

-
hallo Twister
ich machs einfach so
als Beispiel das Einbinden der MSADO.DLL
[code] #import "C:\Programme\Gemeinsame Dateien\System\ADO\msado15.dll" rename_namespace("ADOCG") rename("EOF", "EndOfFile")Als Ergebnis hat du dann im Ordner /Debug oder /Release eine Datei mit der Endung .tli, wo die Schnittstelle zur DLL beschrieben steht.
Es gibt aber noch andere Möglichkeiten die Methoden einer DLL zu nutzen. Siehe dazu unter anderem
http://en.wikipedia.org/wiki/Dynamic_link_libraryGruß
-
Naja, wollt jetzt nicht unbedingt noch auf ne andere Methode umsteigen in der noch *.tli Dateien auftauchen.
Eigentlich sollte das oben ja funktionieren. Die Frage ist einfach, wo der Fehler herkommt
Hängt es irgendwie mit der string-Klasse zusammen oder was kann das sein?
-
Welche Runtime Version verwendest du?
Wenn du DLLs mit C++ Schnittstelle verwenden willst solltest du immer die DLL Runtime verwenden, sonst wird das meist nix.p.S.: vergiss das "#import", das hat mit deinem Problem nix zu tun, das ist für COM Zeugs und nicht "normale" DLLs.
-
also ich benutze fürs ganze schon meine Release-Version der dll.
Sowohl die dll als auch mein 2. Projekt werden mit der MVC 6.0 geschrieben.Kanns evtl daran liegen, dass es nicht reicht die Klasse mit __declspec(dllexport) zu exportieren, sondern dass ich das bei jeder Funktion der Klasse machen muss?
-
Nö, __declspec(dllexport) auf die Klasse reicht.
Die Warning kannst du im übrigen vergessen.
Was jetzt noch zu tun wäre... wenn das Programm ccompiliert wird welches die DLL verwenden soll sollte dort nicht __declspec(dllexport) sondern __declspec(dllimport) (oder garnix) stehen.
Das macht man meist über ein #define:#ifdef MY_DLL_BUILDING #define MY_DLL_EXPORT __declspec(dllexport) #else #define MY_DLL_EXPORT __declspec(dllimport) #endif class MY_DLL_EXPORT foo { };Dann musst du nurnoch in den Projekt-Einstellungen für die DLL einstellen dass MY_DLL_BUILDING auch definiert ist, und in der Applikation eben nicht.
-
irgendwie hats mit dem definieren von MY_DLL_BUILDING nicht so ganz geklappt^^
Aber wenn ich einfadch den Header nachträglich abänder, dass dort nicht mehr dllexport sondern garnichts steht, dann funktionierts
Danke für die Hilfe!
-
Hi, I will try this in German: wie kann ich mit Dependency walker arbeiten? muss ich bestimmte Dateien oder das ganze Projekt laden? kann man Dependency Walker fur standard dll problemem ohne export/import verwenden?
Danke
hustbaer schrieb:
Du erhältst dann keine .lib Datei wenn deine DLL nix exportiert.
Schreib in den Code mal (auf File-Scope) einfach
__declspec(dllexport) int test234 = 0;rein, und compilier das ganze nochmal. Dann solltest du eine .lib haben.
Achja: was exportiert wird kann man leicht mit www.dependencywalker.com angucken.
-
IKS2007 schrieb:
Hi, I will try this in German: wie kann ich mit Dependency walker arbeiten? muss ich bestimmte Dateien oder das ganze Projekt laden? kann man Dependency Walker fur standard dll problemem ohne export/import verwenden?
Danke
hustbaer schrieb:
Du erhältst dann keine .lib Datei wenn deine DLL nix exportiert.
Schreib in den Code mal (auf File-Scope) einfach
__declspec(dllexport) int test234 = 0;rein, und compilier das ganze nochmal. Dann solltest du eine .lib haben.
Achja: was exportiert wird kann man leicht mit www.dependencywalker.com angucken.You just copy dependency-walker somewhere on your system, and start it. Once it runs use the menu item "Options -> Configure Handeled File Extensions" to specify for which file extensions dependency walker should "register" itself. I use DLL, SYS, OCX, SO, and EXE.
After that you can close dependency-walker. Whenever you want to view some DLL (or SYS/OCX/SO/EXE) with dependency-walker you can simply select "View Dependencies" from the context menu for the file in explorer (for DLLs you can also just double-click them, since normally there is no other "verb" available, so "View Dependencies" becomes the default).What dependency walker can do is just show you certain properties of the DLL, and if every import can be resolved on your current system. Give it a try and you'll see. If you load your EXE in dependency-walker you'll see the whole dependency-tree, i.e. if your EXE uses SomeDll.DLL, you'll also see the dependencies of SomeDll.DLL.
However I don't think that it will help you trace down your NTDLL.DLL problem you posted in the "MFC" forum. OTOH, if dependency-walker crashes too when viewing your DLL/EXE that might mean that the PE image (your DLL/EXE) is somehow "invalid" or "damaged".
-
Twister schrieb:
irgendwie hats mit dem definieren von MY_DLL_BUILDING nicht so ganz geklappt^^
Aber wenn ich einfadch den Header nachträglich abänder, dass dort nicht mehr dllexport sondern garnichts steht, dann funktionierts
Danke für die Hilfe!
Wenn du den Header nachträglich abänderst ist das aber doof, da du immer 2 Versionen des selben Header Files rumkugeln hast.
(oder eine Version die aber nur entweder zum Bauen der DLL oder zum verwenden der DLL, aber nicht für das jeweils andere zu gebrauchen ist - was genauso doof ist)Wenn du es über die Projekteinstellungen nicht hinbringst kannst du im DLL Code immer noch in jedes CPP File ganz oben "#define MY_DLL_BUILDING" reinschreiben (vor allen includes), oder, falls du PCH verwendest, ins PCH Header File für die DLL.
Das ist zwar auch unschön, aber IMO immer noch schöner als das Header File nachträglich zu ändern.
-
THANK YOU VERY MUCH! It helped me a lot. I never had to use DLL in the past and I have no expeirence with it at all. I have checked the dll dependencies in my exe file and could see that some modules were highlighted in red, green and blue. Do you know what the colours mean? Does red means that this dll module is causing a problem? I am getting also a message saying that at least one of the modules have a delay load dependency? What does this mean?
Many Thanks again
Regards
hustbaer schrieb:
IKS2007 schrieb:
Hi, I will try this in German: wie kann ich mit Dependency walker arbeiten? muss ich bestimmte Dateien oder das ganze Projekt laden? kann man Dependency Walker fur standard dll problemem ohne export/import verwenden?
Danke
hustbaer schrieb:
Du erhältst dann keine .lib Datei wenn deine DLL nix exportiert.
Schreib in den Code mal (auf File-Scope) einfach
__declspec(dllexport) int test234 = 0;rein, und compilier das ganze nochmal. Dann solltest du eine .lib haben.
Achja: was exportiert wird kann man leicht mit www.dependencywalker.com angucken.You just copy dependency-walker somewhere on your system, and start it. Once it runs use the menu item "Options -> Configure Handeled File Extensions" to specify for which file extensions dependency walker should "register" itself. I use DLL, SYS, OCX, SO, and EXE.
After that you can close dependency-walker. Whenever you want to view some DLL (or SYS/OCX/SO/EXE) with dependency-walker you can simply select "View Dependencies" from the context menu for the file in explorer (for DLLs you can also just double-click them, since normally there is no other "verb" available, so "View Dependencies" becomes the default).What dependency walker can do is just show you certain properties of the DLL, and if every import can be resolved on your current system. Give it a try and you'll see. If you load your EXE in dependency-walker you'll see the whole dependency-tree, i.e. if your EXE uses SomeDll.DLL, you'll also see the dependencies of SomeDll.DLL.
However I don't think that it will help you trace down your NTDLL.DLL problem you posted in the "MFC" forum. OTOH, if dependency-walker crashes too when viewing your DLL/EXE that might mean that the PE image (your DLL/EXE) is somehow "invalid" or "damaged".
-
http://www.dependencywalker.com/help/html/hidr_module_tree_view.htm
Missing exports from delay loaded DLLs are a "perfectly normal" thing if they originate in a system DLL. So MSHTML.DLL having a (delay loaded) "missing export" from MSJAVA.DLL ist _not_ a problem, since MSHTML.DLL knows how to handle it.