2009-08-05 3 views
25

Ich brauche Hilfe beim Schreiben von plattformübergreifendem Code; keine Anwendung, sondern eine Bibliothek.C++ plattformübergreifende dynamische Bibliotheken; Linux und Windows

Ich erstelle eine Bibliothek sowohl statische als auch dynamische mit den meisten der Entwicklung in Linux gemacht, ich habe die statische und gemeinsam genutzte Bibliothek in Linux generiert, wollte jetzt aber eine Windows-Version einer statischen und dynamischen Bibliothek im Formular generieren von .lib und .dll mit dem gleichen Quellcode.

Ist das möglich? Ich bin ein bisschen besorgt, weil ich festgestellt habe, Windows .dll Dateien mit Hilfe von _dllspec oder etwas ähnliches in Ihrem Quellcode zu erzeugen.

Wenn nicht, kann mir jemand die beste und schnellste Lösung empfehlen, um meinen Code auf Windows zu kompilieren. Ich muss das Kompilieren unter Linux nicht machen, ich mache das gerne direkt unter Windows. Außerdem verwende ich zwei externe Bibliotheken, Boost und Xerces XML, die ich sowohl auf meinem Windows als auch auf meinem Linux-System installiert habe, also sollten sie hoffentlich kein Problem darstellen.

Was ich wirklich will, ist eine einzige Quellcode-Kopie, die unter Linux und Windows kompiliert werden kann, um Bibliotheken für jede Plattform zu generieren. Es ist mir egal, ob ich meinen Code zugunsten von Windows oder Linux bearbeiten muss, solange ich eine einzige Quellcode-Kopie haben kann.

+0

Cross-Compiling bezieht sich normalerweise auf das Erstellen von Software auf einer Plattform, die auf einer anderen ausgeführt werden soll. Da Sie sagen, dass Sie Quellcode möchten, der sowohl unter Linux als auch unter Windows kompiliert werden kann, geht es bei Ihrer Frage mehr um das Schreiben einer portablen, plattformübergreifenden Quellcode-Basis als um das Cross-Compilieren. –

+0

GIYF Eigentlich in diesem Fall libtool ist dein Freund ... –

+0

Während Sie auf Antworten warten Besuche CMake: http://www.cmake.org/ – Pete

Antwort

18

Im Allgemeinen gibt es zwei Probleme, die Sie mit betroffen werden müssen:

  1. Die Anforderung, dass auf Windows DLL explizit Symbole exportiert, die an die Außenwelt sichtbar sein soll (über __declspec(dllexport) und
  2. auf
  3. die Möglichkeit, das Build-System zu erhalten (im Idealfall keine separate Make-Datei und Microsoft Visual C++ Projekt/Lösung zu erhalten, die)

zum ersten, müssen Sie über __declspec(dllexport) lernen. Nur Windows-Projekte, typischerweise wird dies in der Weise implementiert, wie ich sie in meiner Antwort auf this question beschrieben habe. Sie können dies noch einen Schritt weiterführen, indem Sie sicherstellen, dass Ihr Exportsymbol (z. B. MY_PROJECT_API) definiert ist, aber beim Erstellen für Linux auf nichts erweitert wird. Auf diese Weise können Sie die Exportsymbole Ihrem Code hinzufügen, wie es für Windows erforderlich ist, ohne den Linux-Build zu beeinträchtigen.

Für die zweite können Sie eine Art von Cross-Plattform-Build-System untersuchen.

Wenn Sie mit dem GNU-Toolset vertraut sind, möchten Sie vielleicht libtool untersuchen (möglicherweise in Verbindung mit automake und autoconf). Die Tools werden nativ unter Linux unterstützt und unter Windows entweder über Cygwin oder MinGW/MSYS unterstützt. MinGW bietet Ihnen auch die Möglichkeit des Cross-Compilings, dh das Erstellen Ihrer nativen Windows-Binärdateien während der Ausführung von Linux. Zwei Ressourcen, die ich beim Navigieren der Autotools (einschließlich libtool) hilfreich gefunden habe, sind die "Autobook" (speziell der Abschnitt DLLs and Libtool) und Alexandre Duret-Lutz's PowerPoint slides.

Wie andere schon erwähnt haben, ist CMake auch eine Option, aber ich kann selbst nicht dafür sprechen.

+0

danke, ich habe einige Google-Suche und denke, ich suchte die falschen Dinge, Libtool klingt interessant und vielleicht cmake als jemand oben erwähnt. Ich bin etwas neu in Linux, so dass diese Tools nicht schnell eine Glocke klingeln: p –

9

Sie können es ziemlich einfach mit # ifdefs tun. Unter Windows _WIN32 vom Compiler (auch für 64-Bit), so Code wie

#ifdef _WIN32 
# define EXPORTIT __declspec(dllexport) 
#else 
# define EXPORTIT 
#endif 

EXPORTIT int somefunction(); 

sollte OK für Sie arbeiten definiert werden sollte.

+0

hmm ja dachte ich darüber, ich werde sehen, wie das gehen würde, könnte dies als meine letzte Zuflucht, wenn ich kein Glück mit der haben über Werkzeuge –

+0

@iQ: Du wirst das noch tun müssen, sogar mit den oben genannten Werkzeugen. Sie behandeln nicht den Export für Sie, sie verstecken nur einige der Unterschiede zwischen dem Build-Prozess auf den verschiedenen Plattformen. –

+0

yeah Ich denke du hast recht, ich werde Makros benutzen müssen. Ich versuche gerade, Codeblocks zu betrachten, die meiner Meinung nach automatisch eine .def-Datei für Sie definieren können, obwohl ich nicht weiß, wie gut oder schlecht das ist. Ich werde ein bisschen experimentieren müssen. –

7

Vielleicht ist es besser, wenn Sie hinzufügen extern "C" !!!,

/* Datei CMakeLists.txt */

SET (LIB_TYPE SHARED) 

ADD_LIBRARY(MyLibrary ${LIB_TYPE} MyLibrary.h) 

/* Datei MyLibrary.h */

#if defined(_WIN32) || defined(__WIN32__) 

    #if defined(MyLibrary_EXPORTS) // add by CMake 

    #define MYLIB_EXPORT extern "C" __declspec(dllexport) 
    #else 

    #define MYLIB_EXPORT extern "C" __declspec(dllimport) 

    #endif /* MyLibrary_EXPORTS */ 

#elif defined(linux) || defined(__linux) 

#define MYLIB_EXPORT 

#endif 


MYLIB_EXPORT inline int Function(int a) 

{ 
    return a ; 
} 
+1

Für die Liebe Gottes, bitte, verwenden Sie ein schöneres Format! – tstenner

+0

@tstenner du meinst zu sagen, du liebst es nicht einfach, wenn Leute ihren eigenen Formatierungsstil während des Schreibens ihres Codes selbst erfinden? :) –

+0

@tstenner einverstanden .. dieses "format" es ist auch .. wie kann ich sagen .. –