Reine C++ Projekt erstellen und anwenden.
-
Jetzt verstehe ich nicht
Wenn ich noch einen Dummy projekt als DLL erstelle, muss ich eigentlich beide Datei (DLL file und lib file) bekomme.
z.B dieses Projekt als DLL Projekt:MathFuncsDLL.h
#include <iostream> #ifdef MATHFUNCSDLL_EXPORTS #define MATHFUNCSDLL_API __declspec(dllexport) #else #define MATHFUNCSDLL_API __declspec(dllimport) #endif extern "C" MATHFUNCSDLL_API double Add(double a, double b); // Returns a - b extern "C" MATHFUNCSDLL_API double Subtract(double a, double b); // Returns a * b extern "C" MATHFUNCSDLL_API double Multiply(double a, double b); // Returns a / b // Throws const std::invalid_argument& if b is 0 extern "C" MATHFUNCSDLL_API double Divide(double a, double b);MathFuncsDLL.cpp
#include "stdafx.h" #include "MathFuncsDll.h" #include <stdexcept> using namespace std; double Add(double a, double b) { return a + b; } double Subtract(double a, double b) { return a - b; } double Multiply(double a, double b) { return a * b; } double Divide(double a, double b) { if (b == 0) { throw invalid_argument("b cannot be zero!"); } return a / b; }--> Okay der Code ist keine C++ sondern eher C
-
Niko_gast schrieb:
Es werden keine Fehlermeldungen geworfen
Und die Warnungen ignorierst du?
Erstens sind Bezeichner mit doppelten Unterstrichen reserviert.
Zweitens muss es class DLLIMPORT Person heißen.
Drittens sollte nichts vor der Include-Direktive für den vorcompilierten Header stehen.
-
Nein musst du nicht, die dll brauchst du wenn du dynamisch linkst und die Lob wenn du statisch linkst.
Ich schau aber gerne. Nochmal nach sobald ich in der Firma meinen VS wieder vor mir hab.
MfG mdn
-
MFK schrieb:
Niko_gast schrieb:
Es werden keine Fehlermeldungen geworfen
Und die Warnungen ignorierst du?
Erstens sind Bezeichner mit doppelten Unterstrichen reserviert.
Zweitens muss es class DLLIMPORT Person heißen.
Drittens sollte nichts vor der Include-Direktive für den vorcompilierten Header stehen.Ich habe meine Code jetzt angepasst :
Person.h#pragma once #include <iostream> #include <string> #include <windows.h> #ifdef _DLL_ # define DLLIMPORT __declspec(dllexport) #else # define DLLIMPORT __declspec(dllimport) #endif class DLLIMPORT Person { std::string _sName; std::string _sVorname; std::string _sGeschlecht; int _iAlter; public: Person(); Person(std::string sName, std::string sVorname, std::string sGeschlecht, int iAlter); ~Person(); const std::string GetName(); const std::string GetVorname(); const std::string GetGeschlecht(); const int GetAlter(); void SetName(const std::string sName); void SetVorname(const std::string sVorname); void SetGeschlecht(const std::string sGeschlecht); void SetAlter(const int iAlter); std::string SagHallo(); };Person.cpp ist wie gelcih geblieben
--> Es wird jetzt eine DLL file und lib file erstellt allerdings mit mehrere Warnungen wie z.B:
warning C4273: 'Person::Person' : inconsistent dll linkage
warning C4273: 'Person::Person' : inconsistent dll linkage
warning C4273: 'Person::~Person' : inconsistent dll linkage
warning C4273: 'Person::GetName' : inconsistent dll linkage.. die Warnungen betreffen alle Funktionen der Class Person
Danke in voraus
-
Marc-O schrieb:
Nein musst du nicht, die dll brauchst du wenn du dynamisch linkst und die Lob wenn du statisch linkst.
Falsch. Unter windows mit dem VC++ compiler gibt es immer einer .lib datei.
Denn der linker erwartet immer eine .lib dateiDie .lib enthält im falle eines DLL projektes informationen über all exportierten Symbole.
Im Falle einer statischen lib enthält es den kompletten object code.
-
Erstens sind Bezeichner mit doppelten Unterstrichen reserviert.
Zweitens sollte nichts vor der Include-Direktive für den vorcompilierten Header stehen.
-
MFK schrieb:
Erstens sind Bezeichner mit doppelten Unterstrichen reserviert.
.Das ist schon erledigt oder (seh Person.h)?
MFK schrieb:
Zweitens sollte nichts vor der Include-Direktive für den vorcompilierten Header stehen. .
ehrlich gesagt weiss ich nicht genau was du meinst

-
Niko_gast schrieb:
Das ist schon erledigt oder (seh Person.h)?
Stimmt, mein Fehler. Bezeichner, die mit einem Unterstrich und einem Großbuchstaben anfangen, sind aber auch reserviert

Niko_gast schrieb:
ehrlich gesagt weiss ich nicht genau was du meinst

In Person.cpp steht die Include-Direktive für den vorcompilierten Header:
#include "StdAfx.h"Es sollte nichts vor dieser Zeile stehen. Deine Define-Direktive gehört also dahinter.
-
Es wurde erledigt aber die genannten warnungen sind immer noch da
-
Hallo wenn ich meine Person.h so umschreibe:
#pragma once #include <iostream> #include <string> #include <windows.h> //#ifdef _DLL_ //# define DLLIMPORT __declspec(dllexport) //#else //# define DLLIMPORT __declspec(dllimport) //#endif class __declspec(dllexport) Person { std::string _sName; std::string _sVorname; std::string _sGeschlecht; int _iAlter; public: Person(); Person(std::string sName, std::string sVorname, std::string sGeschlecht, int iAlter); ~Person(); const std::string GetName(); const std::string GetVorname(); const std::string GetGeschlecht(); const int GetAlter(); void SetName(const std::string sName); void SetVorname(const std::string sVorname); void SetGeschlecht(const std::string sGeschlecht); void SetAlter(const int iAlter); std::string SagHallo(); };Ich bekomme denn keine Warnung mehr
-
Niko_gast schrieb:
Hallo wenn ich meine Person.h so umschreibe:
Ich bekomme denn keine Warnung mehr
Du kannst diesen Header dann aber nicht mehr in Programmen verwenden, die die DLL benutzen sollen. Die brauchen an dieser Stelle dllimport.
Steht DLLIMPORT bei allen Methodendefinitionen?
-
Hast du denn in deinem DLL-Projekt das Symbol "_DLL_" über die Projekt-Einstellungen auch definiert? (Findest du über C/C++ -> Präprozessor, dort sollte es bei den Präprozessordefinitionen eingetragen sein.)
Bei deinen Projekten, die die DLL dann verwenden aber nicht.
@firefly: jup des mit der lib bei einer dll hab ich irgendwie verdrängt

Mfg mdn
-
[quote="MFK"]
Niko_gast schrieb:
Steht DLLIMPORT bei allen Methodendefinitionen?
Nein
Person.cpp Teil ist gleich geblieben
-
Marc-O schrieb:
Hast du denn in deinem DLL-Projekt das Symbol "_DLL_" über die Projekt-Einstellungen auch definiert? (Findest du über C/C++ -> Präprozessor, dort sollte es bei den Präprozessordefinitionen eingetragen sein.)
Mfg mdnes ist genau das
danke
-
Hallo,
ich muss noch mal fragen
ich will jetzt den erzeugten DLL einfach testen
Es gibt zwei Möglichkeiten: ich habe mich für die schwierige entschieden.
ich bin so vorgegangen:C++ projekt erstellen als Console Anwendung:
main.cpp// CPP_DLL_Test.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <string> #include <iostream> #include <windows.h> typedef string (*GetName)(); typedef string (*GetVorname)(); typedef string (*GetGeschlecht)(); typedef int (*GetAlter)(); int main() { GetName _GetName; GetVorname _GetVorname; GetGeschlecht _GetGeschlecht; GetAlter _GetAlter; HINSTANCE hInstLibrary = ::LoadLibrary("CPP_DLL.dll"); if (hInstLibrary) { _GetName = (GetName)::GetProcAddress(hInstLibrary, "GetName"); _GetVorname = (GetVorname)::GetProcAddress(hInstLibrary, "GetVorname"); _GetGeschlecht = (GetGeschlecht)::GetProcAddress(hInstLibrary, "GetGeschlecht"); _GetAlter = (GetAlter)::GetProcAddress(hInstLibrary, "GetAlter"); if (_GetName) { std::cout << "DLL GetName Called " << std::endl; } FreeLibrary(hInstLibrary); } else { std::cout << "DLL Failed To Load!" << std::endl; } std::cin.get(); return 0; }Ist meine Vorgehen richtig?
-
Eher nicht.
Zum einen hast du den Header, über den du alle Definition der Klasse hast (Kannst also die Funktiondeklarationen weglassen), auserderm sind deine Funktionen, keine Freistehenden, sondern Member-Funktionen einer Klasse, daher glaub ich nicht, das du die so aufrufen könntest (Brauchst ja ein Objekt der Klasse).
Daher einfacheres Vorgehen:
- Erzeuge ein Konsolen-Projekt (hast du ja schon)
- kopiere deine .h, .lib, .dll in die naehe deines neuen Projektes
- Passe deine include- und lib-Pfad auf die vorher kopierten Dateien an
- Dann füge noch einen Verweis auf die DLL hinzu
- Includiere den Header in deiner "CPP_DLL_Test.cpp"
- Benutze das Klasse nun so als hättest du sie in diesem Projekt geschrieben
Mfg mdn
-
Marc-O schrieb:
Daher einfacheres Vorgehen:
- Erzeuge ein Konsolen-Projekt (hast du ja schon)
- kopiere deine .h, .lib, .dll in die naehe deines neuen Projektes
- Passe deine include- und lib-Pfad auf die vorher kopierten Dateien an
- Dann füge noch einen Verweis auf die DLL hinzu
- Includiere den Header in deiner "CPP_DLL_Test.cpp"
- Benutze das Klasse nun so als hättest du sie in diesem Projekt geschrieben
Mfg mdn
Dieses vorgehen bringt mir nicht viel, da ich eigentlcih keine Lib File verwenden möchte.
Ich möchte auch nicht den Headerfile verwende.Ich möchte nur der DLL File benutzen.
Ich habe einen Dummy Projekt(ausschliesslich C) erstellt, wo ich auch so vorgegangen bin:#include "stdafx.h" #include <iostream> #include <windows.h> typedef double (*AddFunc)(double,double); typedef double (*Subtract)(double,double); typedef double (*Multiply)(double,double); typedef double (*Divide)(double,double); int main() { AddFunc _AddFunc; Subtract _Subtract; Multiply _Multiply; Divide _Divide; HINSTANCE hInstLibrary = ::LoadLibrary("Dummy_DLL.dll"); if (hInstLibrary) { _AddFunc = (AddFunc)::GetProcAddress(hInstLibrary, "Add"); _Subtract = (Subtract)::GetProcAddress(hInstLibrary, "Subtract"); _Multiply = (Multiply)::GetProcAddress(hInstLibrary, "Multiply"); _Divide = (Divide)::GetProcAddress(hInstLibrary, "Divide"); if (_AddFunc) { std::cout << "23 + 43 = " << _AddFunc(23, 43) << std::endl; } if (_Subtract) { std::cout << "55 - 43 = " << _Subtract(55, 43) << std::endl; } if (_Multiply) { std::cout << "60 * 10 = " << _Multiply(60, 10) << std::endl; } if (_Divide) { std::cout << "300 / 50 = " << _Divide(300, 50) << std::endl; } FreeLibrary(hInstLibrary); } else { std::cout << "DLL Failed To Load!" << std::endl; } std::cin.get(); return 0; }
-
Niko_gast schrieb:
Dieses vorgehen bringt mir nicht viel, da ich eigentlcih keine Lib File verwenden möchte.
Warum war es dann ein Problem, dass keine Lib-Datei erstellt wurde?
Niko_gast schrieb:
Ich möchte auch nicht den Headerfile verwende.
Dann war das Gehampel mit der Umschaltung zwischen dllimport und dllexport unnötig.
Wenn du unbedingt über LoadLibrary/GetProcAddress gehen willst:
Erstens passen deine Funktions-Typedefs nicht zu den exportierten Methoden.
Zweitens passen die Namen der Symbole nicht. Schau dir mit dem Dependency Walker an, unter welchem Namen die DLL deine Methoden exportiert .
-
Dann sollten die Funktionen mittels
extern "C"deklariert werden (damit das C++ Name Mangeling abgestellt wird).
Und außerdem natürlich dann als freie (bzw. static Klassen-) Funktionen.
Aber welchen Sinn macht es, die DLL dynamisch per LoadLibrary zu laden (anstatt direkt dem Projekt hinzuzufügen)? Möchtest du ein Plugin-System verwenden?
-
MFK schrieb:
Niko_gast schrieb:
Dieses vorgehen bringt mir nicht viel, da ich eigentlcih keine Lib File verwenden möchte.
Warum war es dann ein Problem, dass keine Lib-Datei erstellt wurde?
Nein Lib ist schon erstellt wordenNiko_gast schrieb:
Ich möchte auch nicht den Headerfile verwende.
Dann war das Gehampel mit der Umschaltung zwischen dllimport und dllexport unnötig.
Wenn du unbedingt über LoadLibrary/GetProcAddress gehen willst:
1)Erstens passen deine Funktions-Typedefs nicht zu den exportierten Methoden.
2)Zweitens passen die Namen der Symbole nicht. Schau dir mit dem Dependency Walker an, unter welchem Namen die DLL deine Methoden exportiert .- warum nicht?
2)Ich habe schon geschaut und es stimmt.
- warum nicht?