Inkonsistente DLL-Bindung. dllexport angenommen
-
Hi,
ich habe ein kleines Problem mit einer DLL, die ich erstellen möchte. Vielleicht kann mir jemand kurz sagen, was an folgendem Code falsch ist? Ich danke vielmals!
Header:
#ifdef TESTER #define DLLTEST __declspec(dllexport) #else #define DLLTEST __declspec (dllimport) #endif int DLLTEST Sum (int Length, int Height); class DLLTEST cData { public: cData::cData () : m_iX (0) {} void SetX (int a); int GetX (); private: int m_iX; };
Source
#include "DllTest.h" int Sum(int Length, int Height) { return (Length + Height); } void cData::SetX (int a) { m_iX = a; } int cData::GetX () { return m_iX; }
Fehlermeldung:
warning C4273: 'Sum' : Inkonsistente DLL-Bindung. dllexport angenommen.
Danke nochmals!
-
Hallo,
so:
include "DllTest.h" #ifdef TESTER /* alle zu exportierenden Funktionen kommen in diesen Block (Klassen nicht) */ int Sum(int Length, int Height) { return (Length + Height); } // weitere Funktionen, die exportiert werden sollen #endif void cData::SetX (int a) { m_iX = a; } int cData::GetX () { return m_iX; }
wäre es möglich.
MfG,
Probe-Nutzer
-
Muss heißen:
int cData::Sum(int Length, int Height) { return (Length + Height); }
-
Und jetzt die korrekte Antwort:
Du musst bei den Funktionen im Sourcefile dieselben Modifizierer wie im Header angeben. Damit fehlt bei der Funktion Sum das DLLTEST.
-
LordJaxom schrieb:
Und jetzt die korrekte Antwort:
Du musst bei den Funktionen im Sourcefile dieselben Modifizierer wie im Header angeben. Damit fehlt bei der Funktion Sum das DLLTEST.
Das ist nicht korrekt! Für __declspec (dllim/export) genügt dies bei der Klassen Deklaration!
-
Martin Richter schrieb:
Das ist nicht korrekt! Für __declspec (dllim/export) genügt dies bei der Klassen Deklaration!
Sum ist aber eine freie Funktion.
-
und was war meine Korrektur?
Ich zitiere meine eigene Email:
int cData::Sum(int Length, int Height)
Die Modifier haben hier nichts zu tun.
Dem Linker fehlt einfach für die Export Tabelle die Adresse der Funktion!
-
Martin Richter schrieb:
und was war meine Korrektur?
Ich zitiere meine eigene Email:
int cData::Sum(int Length, int Height)
Die Modifier haben hier nichts zu tun.
Dem Linker fehlt einfach für die Export Tabelle die Adresse der Funktion!Ok, nochmal ganz von vorne:
Im OP ist die Deklaration von Sum die Deklaration einer freien Funktion außerhalb der Klasse cData. Deshalb ist die Definition von Sum als Mitglied der Klasse falsch. Und da bei freien Funktionen die Modifizierer sehr wohl bei Deklaration und Definition relevant sind, fehlt in der Definition von Sum das DLLTEST.
Wenn Sum eine Memberfunktion der Klasse cData wäre, dann gebe ich Dir recht, dass bereits der Modifizierer in der Klassendefinition ausreicht. Das ist aber nunmal leider nicht der Fall, und eine Verschiebung in die Klasse - noch dazu als nichtstatische Funktion - nur zu dem Zwecke, die DLL-Bindung der Klasse auch auf Sum anzuwenden, macht einfach keinen Sinn.
-
Hallo,
fragt sich nur, ob diese Korrektur (aus der Sicht des Hilfe suchenden) erwünscht ist ;). Ich habe es jedenfalls auch anders aufgefasst, sum soll schon nicht Bestandteil der Klasse sein, aber wer weiß...
MfG,
Probe-Nutzer
-
LordJaxom schrieb:
Und da bei freien Funktionen die Modifizierer sehr wohl bei Deklaration und Definition relevant sind, fehlt in der Definition von Sum das DLLTEST.
Das ist nicht korrekt, ein simples Hinzufügen von DLLTEST bei der Definition führt zum Fehler:
error C2491: 'Sum' : definition of dllimport function not allowed
wenn TESTER nicht definiert ist.
Klappt also zumindest nicht in jedem Falle...meine Lösung liegt also noch ganz gut im Rennen...
MfG,
Probe-Nutzer
-
Probe-Nutzer schrieb:
Das ist nicht korrekt, ein simples Hinzufügen von DLLTEST bei der Definition führt zum Fehler:
error C2491: 'Sum' : definition of dllimport function not allowed
wenn TESTER nicht definiert ist.
Stimmt. Aber Tester sollte bei der Erstellung der DLL doch immer definiert sein. Und bei der Benutzung der DLL sollte dieses Sourcefile garnicht übersetzt werden. Und wenn während der DLL-Erzeugung durch das #define die Funktion für den Compiler sichtbar wird, ist das Problem doch dasselbe - im Header steht __declspec(dllexport), im Sourcefile wird Sum garnicht modifiziert. Dadurch kam es doch überhaupt erst zu der Warnung. Oder steh' ich jetzt auf dem Schlauch?
-
LordJaxom schrieb:
Aber Tester sollte bei der Erstellung der DLL doch immer definiert sein.
Ja, natürlich...
LordJaxom schrieb:
Und bei der Benutzung der DLL sollte dieses Sourcefile garnicht übersetzt werden.
Wenn das die DLL nutzende Modul kompiliert wird, wandert doch auch nur der Header in das andere Projekt, passt also...
LordJaxom schrieb:
Und wenn während der DLL-Erzeugung durch das #define die Funktion für den Compiler sichtbar wird, ist das Problem doch dasselbe - im Header steht __declspec(dllexport), im Sourcefile wird Sum garnicht modifiziert.
Nein, das Problem tritt hier nicht auf, denn eine "export-Deklaration" muss nicht bei der Definition wiederholt werden.
LordJaxom schrieb:
Dadurch kam es doch überhaupt erst zu der Warnung.
Die Warnung entstand (so erkläre ich es mir zumindest), weil der Compiler, im Falle einer "import-Deklaration" (TESTER nicht #defined) verwirrt wird, wenn er dann im Source plötzlich auf die Definition trifft (die soll doch importiert werden
) und annimmt, man will wohl doch exportieren...
LordJaxom schrieb:
Oder steh' ich jetzt auf dem Schlauch?
Vielleicht jetzt nicht mehr? Oder übersehe ich hier etwas...
MfG,
Probe-Nutzer
-
Probe-Nutzer schrieb:
LordJaxom schrieb:
Dadurch kam es doch überhaupt erst zu der Warnung.
Die Warnung entstand (so erkläre ich es mir zumindest), weil der Compiler, im Falle einer "import-Deklaration" (TESTER nicht #defined) verwirrt wird, wenn er dann im Source plötzlich auf die Definition trifft (die soll doch importiert werden
) und annimmt, man will wohl doch exportieren...
Ahh, das erklärt einiges.
Dann ist der eigentliche Fehler also nicht, wie ich glaubte, dass bei der Definition von Sum beim Erstellen der DLL der Export fehlt. Sondern, dass beim Erstellen eines Klienten der DLL plötzlich eine Definition vorhanden ist.
Dann sollte die Lösung aber sein, das entsprechende Modul einfach nicht im Klient der DLL zu übersetzen, denn das gehört da nicht hin
-
LordJaxom schrieb:
Sondern, dass beim Erstellen eines Klienten der DLL plötzlich eine Definition vorhanden ist.
Das Problem entsteht aber doch auch schon, wenn nur die DLL selbst erstellt wird, wie es im OP wahrscheinlich gemeint war.
LordJaxom schrieb:
Dann sollte die Lösung aber sein, das entsprechende Modul einfach nicht im Klient der DLL zu übersetzen, denn das gehört da nicht hin
Das war für mich nie der Punkt, siehe oben, der Klient muss zur Übersetzung eigentlich nur den Header "sehen".
MfG,
Probe-Nutzer
-
Probe-Nutzer schrieb:
LordJaxom schrieb:
Sondern, dass beim Erstellen eines Klienten der DLL plötzlich eine Definition vorhanden ist.
Das Problem entsteht aber doch auch schon, wenn nur die DLL selbst erstellt wird, wie es im OP wahrscheinlich gemeint war.
Beim Erstellen der DLL muss doch eine Definition vorhanden sein, die exportiert werden kann?!? Wie soll die DLL sonst eine Funktion exportieren?
Also, was ich meine:
DLL-Erzeugung: Deklaration und Definition müssen vorhanden sein. Deklaration muss exportiert werden, Definition kann exportiert werden.
DLL-Benutzung: Deklaration muss vorhanden sein, Definition darf nicht vorhanden sein. Deklaration muss importiert werden.
Wie kommt in diesem Szenario die Situation "bei der DLL-Erzeugung trifft der Compiler auf die Definition einer Funktion, die eigentlich importiert werden sollte" zustande?
-
Jetzt stand ich auf der Leitung, das Problem kann ja nur dann in einem "Nur-DLL"-Projekt entstehen, wenn hier vergessen wird, TESTER zu definieren :), was man mit entsprechender Erfahrung wohl nicht übersieht.
So gesehen ist es natürlich unnötig, im Source eine #ifdef/#endif - Direktive um die zu exportierenden Funktionen zu legen und nur dann "hilfreich", wenn die DLL tatsächlich im Klient-Projekt mit übersetzt wird. Wahrscheinlich dachte ich auch an diesen Fall, als ich meinen Lösungsvorschlag geschrieben habe :), aber beim ersten Lesen des OP dachte ich nur, dass TESTER beim Auftreten dieser Warnung nicht definiert sein konnte, und versucht wurde, die DLL allein zu übersetzen.
Zumindest konnte ich mir damit trotzdem die Warnung erklären. :), und ich korrigiere meinen letzten Beitrag:
Das Problem kann aber auch dann schon entstehen, wenn nur die DLL selbst erstellt und dabei vergessen wird, TESTER zu definieren, wie es im OP wahrscheinlich gemeint war.
MfG,
Probe-Nutzer