Reine C++ Projekt erstellen und anwenden.
-
Hallo zusammen,
ich habe einen Test Projekt als C++_DLL mit VS_2008 erstellt.
Es sieht wie folgende aus:
Person.h#pragma once //class Person //{ //public: // Person(void); // ~Person(void); //}; #include <iostream> #include <string> #include <windows.h> #ifdef __DLL__ # define DLLIMPORT __declspec(dllexport) #else # define DLLIMPORT __declspec(dllimport) #endif DLLIMPORT class Person { std::string _sName; std::string _sVorname; std::string _sGeschlecht; int _iAlter; public: DLLIMPORT Person(); DLLIMPORT Person(std::string sName, std::string sVorname, std::string sGeschlecht, int iAlter); DLLIMPORT ~Person(); DLLIMPORT const std::string GetName(); DLLIMPORT const std::string GetVorname(); DLLIMPORT const std::string GetGeschlecht(); DLLIMPORT const int GetAlter(); DLLIMPORT void SetName(const std::string sName); DLLIMPORT void SetVorname(const std::string sVorname); DLLIMPORT void SetGeschlecht(const std::string sGeschlecht); DLLIMPORT void SetAlter(const int iAlter); DLLIMPORT std::string SagHallo(); };Person.cpp
#include "StdAfx.h" #include "Person.h" //Person::Person(void) //{ //} // //Person::~Person(void) //{ //} #define __dll__ #include <iostream> #include <string> #include <windows.h> DLLIMPORT Person::Person() { _sName = ""; _sVorname = ""; _sGeschlecht = ""; _iAlter = 0; } DLLIMPORT Person::Person(std::string sName, std::string sVorname, std::string sGeschlecht, int iAlter) { _sName = sName; _sVorname = sVorname; _sGeschlecht = sGeschlecht; _iAlter = iAlter; } DLLIMPORT Person::~Person() { } DLLIMPORT const std::string Person::GetName() { return _sName; } DLLIMPORT const std::string Person::GetVorname() { return _sVorname; } DLLIMPORT const std::string Person::GetGeschlecht() { return _sGeschlecht; } DLLIMPORT const int Person::GetAlter() { return _iAlter; } DLLIMPORT void Person::SetName(const std::string sName) { _sName = sName; } DLLIMPORT void Person::SetVorname(const std::string sVorname) { _sVorname = sVorname; } DLLIMPORT void Person::SetGeschlecht(const std::string sGeschlecht) { _sGeschlecht = sGeschlecht; } DLLIMPORT void Person::SetAlter(const int iAlter) { _iAlter = iAlter; } DLLIMPORT std::string Person::SagHallo() { char sAlter[5]; sprintf(sAlter, "%d", _iAlter); return "Hallo, ich heisse " + _sVorname + " " + _sName + ", bin " + _sGeschlecht + " und " + sAlter + " Jahre alt."; }--> beim Build bekomme ich folgende Fehlermeldungen:
error C2491: 'Person::Person' : definition of dllimport function not allowed
: error C2491: 'Person::Person' : definition of dllimport function not allowed
: error C2491: 'Person::~Person' : definition of dllimport function not allowed
: error C2491: 'Person::GetName' : definition of dllimport function not allowed
: error C2491: 'Person::GetVorname' : definition of dllimport function not allowed
: error C2491: 'Person::GetGeschlecht' : definition of dllimport function not allowed
: error C2491: 'Person::GetAlter' : definition of dllimport function not allowed
: error C2491: 'Person::SetName' : definition of dllimport function not allowed
: error C2491: 'Person::SetVorname' : definition of dllimport function not allowed
: error C2491: 'Person::SetGeschlecht' : definition of dllimport function not allowed
: error C2491: 'Person::SetAlter' : definition of dllimport function not allowed
: error C2491: 'Person::SagHallo' : definition of dllimport function not alloweddanke in voraus
-
Erstens sind Bezeichner mit doppelten Unterstrichen reserviert.
Zweitens ist __dll__ etwas anderes als __DLL__.
Drittens sollte die Define-Direktive vor der Include-Direktive stehen.
-
Wenn die Klasse schon mit mit Im-/Export markiert ist, ist das für die einzelnen Funktion überflüssig.
-
manni66 schrieb:
Wenn die Klasse schon mit mit Im-/Export markiert ist, ist das für die einzelnen Funktion überflüssig.
Ist zwar lange her das ich mich damit beschäftigt habe, aber früher hatte jedes Beispiel (u.A. msdn) auch die Funktionen mit Im-/Export markiert. Ich würde daher deine Aussage zumindest mit Vorsicht genießen.
-
-
Hallo alle zusammen,
ich meine code so gepasst:
Person.h#pragma once #include <iostream> #include <string> #include <windows.h> #ifdef __DLL__ # define DLLIMPORT __declspec(dllexport) #else # define DLLIMPORT __declspec(dllimport) #endif DLLIMPORT class 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
#define __DLL__ #include "StdAfx.h" #include "Person.h" #include <iostream> #include <string> #include <windows.h> Person::Person() { _sName = ""; _sVorname = ""; _sGeschlecht = ""; _iAlter = 0; } Person::Person(std::string sName, std::string sVorname, std::string sGeschlecht, int iAlter) { _sName = sName; _sVorname = sVorname; _sGeschlecht = sGeschlecht; _iAlter = iAlter; } Person::~Person() { } const std::string Person::GetName() { return _sName; } const std::string Person::GetVorname() { return _sVorname; } const std::string Person::GetGeschlecht() { return _sGeschlecht; } const int Person::GetAlter() { return _iAlter; } void Person::SetName(const std::string sName) { _sName = sName; } void Person::SetVorname(const std::string sVorname) { _sVorname = sVorname; } void Person::SetGeschlecht(const std::string sGeschlecht) { _sGeschlecht = sGeschlecht; } void Person::SetAlter(const int iAlter) { _iAlter = iAlter; } std::string Person::SagHallo() { char sAlter[5]; sprintf(sAlter, "%d", _iAlter); return "Hallo, ich heisse " + _sVorname + " " + _sName + ", bin " + _sGeschlecht + " und " + sAlter + " Jahre alt."; }Es werden keine Fehlermeldungen geworfen, aber es wird kein lib File erstellt.
DLL wird schon erstellt, aber lib File nicht
-
Wenn du eine Lib möchtest, dann musst die dies dem VS2008 auch mitteilen, dieser kann für jede Projekt-Konfiguration entweder eine Dll oder eine lib erstellen.
Nachtrag: Projekt-Eigenschaften -> Allgemein -> Konfigurationstyp: steht wahrscheinlich auf "Dynamische Bibliothek (.dll)" und dies musst du auf "Statische Bibliothek (.lib)" umstellen. Dann solltest du aber die DLLIMPORT nicht mehr.
Mfg mdn
-
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