Codeteile per Flag austauschen
-
Hallo,
ich arbeite zur Zeit in meiner dll mit zwei verschiedenen APIs, die jeweils vom Anwender ein bzw. ausgeschaltet werden können. Dafür habe ich im Code defines gesetzt, die für die jeweilige API greifen.
#ifdef X ... doXStuff #elif Y ... doYStuff #endifDas Problem ist jetzt, dass je nachdem die eine oder andere lib gelinkt wird und ich das natürlich nur im Header machen kann, da ja der cpp source sonst nich gelinkt werden könnte.
Jetzt habe folgende Überlegungen angestellt, wenn ich das per interface gestalte, schließt das ein, dass der Anwender irgendwo eigene implementierungen machen muss, fällt daher also weg.
Die defibition im header ist das naheliegenste, bläht diesen aber auch ziemlich mit funktionsimplementierung auf.
Die dritte möglichkeit, die mir spontan einfällt setzt auf abstrakte Funktionspointer, die je nach situation gebunden werden, Nachteil hier ist aber auch, dass dies zusätzlich Zeit frisst und es sein kann, da die funktionspointer nicht linear sind, dass bei der ein oder anderen api funktionen ungenutzt weil eben falsch aufgebaut sind.
Eine andere Möglichkeit bei der ich nicht weiß ob das so funktioniert wäre eine templatelösung. Wenn ich das richtig verstanden habe, müsste der compiler für das template eine eigene klasse erzeugen und separat linken. Wenn ich die kritischen methoden in einem cpp file für das template definiere, erzeugt der compiler dann auch ohne das lib file gültigen funktionscode?
Wenn ich das template dann verwende müsste er doch den code aus dem template obj mit der im projekt eingebundenen api linken oder?gibt es für das problem villeicht andere Ansätze bei der ich code in der dll ohne lib file trotzdem linken kann?
-
jeweils vom Anwender
Wer ist der Anwender? Jemand, der deinen Code uebersetzt, linkt oder nur deine DLL benutzt?
Nachteil hier ist aber auch, dass dies zusätzlich Zeit frisst und es sein kann
Ja, aber nur einmal.
da die funktionspointer nicht linear sind
Aeh?
gibt es für das problem villeicht andere Ansätze bei der ich code in der dll ohne lib file trotzdem linken kann?
Ja, nennt sich LoadLibrary http://msdn.microsoft.com/de-de/library/ms686944(v=vs.85).aspx .
-
Wie siehts mit einer forward declaration dll->app aus?
//dll //test.h void funcX(); class test { public: void useFuncX(); } //cpp void test::useFuncX() { funcX(); }//app #include <header_declaring_funcx.h> #include <test.h> main() { test().useFuncX(); }
-
ich arbeite zur Zeit in meiner dll mit zwei verschiedenen APIs, die jeweils vom Anwender ein bzw. ausgeschaltet werden können.
Meinst du so was?
// Die Klasse tVisualisiationDevice entspricht einem Interface für beide API's, // welche nur die zusammengefassten Funktionen deklariert. class tVisualisiationDevice { public: virtual void InitDevice(); virtual void ReleaseDevice(); virtual void DrawLine(); }; // Implementierung von tVisualisiationDevice auf DirectX class tDirectXDevice : public tVisualisiationDevice { public: void InitDevice() {} void ReleaseDevice() {} void DrawLine() {} }; // Implementierung von tVisualisiationDevice auf OpenGL class tOpenGLDevice : public tVisualisiationDevice { public: void InitDevice() {} void ReleaseDevice() {} void DrawLine() {} }; tVisualisiationDevice* VisDevice = nullptr; // Ist nicht schön aber für Demo Zwecke genügt es // DLL Funktion zum Umstellen der Visualisierung auf DirectX void SetDirectX() { if (VisDevice != nullptr) { VisDevice->Release(); delete VisDevice; } VisDevice = new tDirectXDevice(); VisDevice->InitDevice(); } // DLL Funktion zum Umstellen der Visualisierung auf OpenGL void SetOpenGL() { if (VisDevice != nullptr) { VisDevice->Release(); delete VisDevice; } VisDevice = new tOpenGLDevice(); VisDevice->InitDevice(); }
-
Pria schrieb:
Die dritte möglichkeit, die mir spontan einfällt setzt auf abstrakte Funktionspointer, die je nach situation gebunden werden,
Lass die Finger von Funktionspointern, das ist C und nicht C++ und schon gar nicht OOP.
Pria schrieb:
Nachteil hier ist aber auch, dass dies zusätzlich Zeit frisst
Programm/Datendesign anhand vermeintlicher oder tatsächlicher Nanosekundenoptimierungen vorzunehmen, ist immer schlecht.
Pria schrieb:
und es sein kann, da die funktionspointer nicht linear sind, dass bei der ein oder anderen api funktionen ungenutzt weil eben falsch aufgebaut sind.
Was sind "nichtlineare" Funktionspointer?
Was sind "falsch aufgebaute" api funktionen?Nutze Vererbung, da hast automatisch Codewiederverwendung;
es wird immer alles gelinkt, zur Laufzeit erzeugst du dann eine Instanz der jeweils gewünschten Klasse.
-
Wutz schrieb:
Was sind "nichtlineare" Funktionspointer?
Was sind "falsch aufgebaute" api funktionen?typedef int (*ptr) (int x, int y); int SomeFunc(int x, int y); //<- mapping möglich int SomeFunc2(float x, int y, float z); //<- zu viele parameter, mappen nicht möglichWutz schrieb:
Nutze Vererbung, da hast automatisch Codewiederverwendung;
es wird immer alles gelinkt, zur Laufzeit erzeugst du dann eine Instanz der jeweils gewünschten Klasse.Dann tritt hier wieder das Problem auf, entweder binde ich alle header und libs in die dll ein oder der anwender muss eine entsprechende implementierung basteln?
-
Pria schrieb:
Wutz schrieb:
Was sind "nichtlineare" Funktionspointer?
Was sind "falsch aufgebaute" api funktionen?typedef int (*ptr) (int x, int y); int SomeFunc(int x, int y); //<- mapping möglich int SomeFunc2(float x, int y, float z); //<- zu viele parameter, mappen nicht möglichEs gibt seit C++11 sowas wie std::function und std::bind, solltest du dir vielleicht mal anschauen.

-
Nathan schrieb:
std::function
aka Vererbung
-
@Pria:
Ich verstehe dein Problem nicht.
Willst du in deiner DLL abhängig von einem Präprozessorflag die API namens A oder die API namens B nutzen? Soll der Benutzer selbst dies kompilieren können?
Oder willst du eine DLL mit Nutzung von A und eine DLL mit Nutzung von B generieren? Und der Benutzer wählt anhand der DLL was er haben möchte.
Oder willst du eine DLL schreiben welche die API's über DLLs anspricht und diese je nach Gegenheit nutzt? Wir kämen dann Richtung COM.
Was möchtest du denn gerne machen?
Skizziere doch mal ein kleines Beispiel!