Namespace in DLLs
-
Hallo Forengemeinde,
Habe da eine Frage bezüglich meinem DLL Code:
#define exp extern "C" __declspec (dllexport) namespace test { int a=0; }; exp void add_a() { test::a++; }; exp void multiply_a() { test::a*=test::a; }; exp int return_a() { return test::a; };Wenn ich diesen code compiliere gibt es keine Fehlermeldung.
Meiner meinung nach müsste test::a jetzt jederzeit(in jeder exportierten Funktion) verfügbar sein, meine Frage nun: ist mein Gedankengang richtig?
Ich frage weil ich wenig Erfahrung mit dem Programmiern von DLLs habe und das Testen sich dementsprechen schwierig gestaltet.
MfG fgd
-
fgd.com schrieb:
...
Zumindest in einer C-Kompatiblen DLL-Schnittstelle sind Namensräume nicht verwendbar (namespace existert nicht unter C). Alles andere kann Compilerspezifisch möglich sein (aber dann ist die DLL auch nur mit dieser Compilerversion kompatibel).
cu André
-
asc schrieb:
fgd.com schrieb:
...
(namespace existert nicht unter C).
In meinem Fall benutze ich C++, wenn jetzt der exportierte Code verwendet wird gibt es dann irgendwelche Schwierigkeiten?
Noch interessanter währe es für mich, ob ich Funktionen aus Klassen herraus exportieren kann, quasi dann die Instanz der Klasse global anlegen,
und in den Exportierten Funktionen darauf zugreifen.Falls nicht währe meine nächste Frage dann, wie man am besten funktionsübergreifende Variablen umsetzen kann, so dass der Code immernoch (mit extern "C"...) exportiert werden kann.
MfG fgd
-
fgd.com schrieb:
asc schrieb:
fgd.com schrieb:
...
(namespace existert nicht unter C).
In meinem Fall benutze ich C++, wenn jetzt der exportierte Code verwendet wird gibt es dann irgendwelche Schwierigkeiten?
C++ garantiert keine binärkompatibilität. Das heißt, wenn du innerhalb einer DLL C++ Feature einsetzt, ist diese DLL in der Regel nur und ausschließlich mit dem Compiler verwendbar, auf dem du diese erstellt hast. Und hier gibt es auch keine Garantie was überhaupt funktioniert (z.B. was passiert wenn eine Exception über DLL-Grenzen hinweg eintritt, und nicht in der Schnittstelle abgefangen wird...). Ich würde z.B. bei Klassen grundsätzlich nur rein abstrakte Basisklassen in der Schnittstelle anbieten, die wiederum nur mit ebenso rein abstraken Datentypen hantieren (Keine Typen der STL...) etc.
In der Regel legt man sich auf eins der folgenden Dinge fest:
a) Reine C-Schnittstelle an der DLL-Grente
b) Compilerspezifische DLL [Hierbei meine spezifisch auch auf die Compilerversion]. Welche Features unterstützt werden ist aber auch Compilerspezifisch.
c) COM-Interface [Windows], ich kenne keinen der COM programmiert und noch nicht darüber geflucht hat, aber wenigstens sind COM-Komponenten einheitlich über Compilergrenzen unter Windows verwendbar.Zudem bist du in dem ANSI C++ Forum eh schon falsch, da ANSI C++ selbst auch garkeine Kenntnisse von DLL's (Betriebssystemspezifisches Feature) hat.
cu André
P.S: Die Probleme mit den Bibliotheken [und der fehlenden Binärkompatibilität zumindestens innerhalb eines Betriebssystems] und der fehlenden Standard-UI sind für mich zwei wesentliche Mankos an der Sprache C++ (Hier finde ich die Umsetzung von .Net deutlich besser).
-
äh... die funktionen sind als extern "C" markiert.
Ich sehe hier keine Probleme mit dem Code.
-
Shade Of Mine schrieb:
äh... die funktionen sind als extern "C" markiert.
Ich sehe hier keine Probleme mit dem Code.
Ich weiß aus eigenen Tests das Namensräume unter Umständen das extern "C" unterwandern (Und dann die Funktion nicht unter den Namen in der DLL zu finden ist).
-
asc schrieb:
Ich weiß aus eigenen Tests das Namensräume unter Umständen das extern "C" unterwandern (Und dann die Funktion nicht unter den Namen in der DLL zu finden ist).
Die Funktionen liegen in keinem namensraum...
-
Shade Of Mine schrieb:
äh... die funktionen sind als extern "C" markiert.
Ich sehe hier keine Probleme mit dem Code.
Wenn es mit dem Code keine Probleme gibt, würde es mich brennend interessieren wie es hiermit aussieht:
#define exp extern "C" __declspec (dllexport) #include "meineklasse.h" namespace test { meineKlasse myTest; }; exp int meineFunktion() { return test::myTest.funktion(); }; exp int meinWert() { return test::myTest.wert; };Halt quasi ein Export von C++ Klassenfunktionen / public Variablen, mit extern "C"
MfG fgd
-
alles problemlos.
was innerhalb der funktion passiert ist deine private sache. da darfst du auch brainfuck verwenden wenn du lustig bist

was wichtig ist, ist die schnittstelle - das öffentliche interface.
eine funktion die int liefert und nichts als parameter nimmt, ist kein problem.
was nicht geht ist, dass du eine objekt einer klasse lieferst. exceptions darfst du keine werfen und wenn du speicher mit new anforderst musst du ihn in der dll wieder freigeben und nicht im client code.