Geben Sie eine plattformübergreifende Header-Datei frei

I. Einleitung

Wenn wir normalerweise Code schreiben, insbesondere wenn wir Räder herstellen ( Bibliotheksdateien für andere bereitstellen ), werden wir auf verschiedene Nachfrageszenarien stoßen:

  1. Einige Benutzer müssen es unter Linux verwenden, andere unter Windows.
  2. Einige Leute verwenden C-Sprache, um sich zu entwickeln, andere verwenden C ++, um sich zu entwickeln;
  3. Einige Benutzer verwenden dynamische Bibliotheken, andere statische Bibliotheken.

Insbesondere im Windows- System muss die exportierte Funktion in der Bibliotheksdatei _declspec (dllexport) verwenden , um die Funktion zu deklarieren, und der Benutzer muss _declspec (dllimport) verwenden , um die Funktion beim Importieren zu deklarieren, was sehr problematisch ist!

Dieser kurze Artikel enthält eine Header-Datei . Mit dieser Header-Datei und einigen Makros, die während der Kompilierung übergeben wurden , können Sie die verschiedenen oben genannten Anforderungen perfekt erfüllen.

Zweitens die Header-Datei

Laden Sie den Code einfach direkt hoch. Sie können versuchen, ihn zuerst zu analysieren. Anschließend analysieren wir nacheinander verschiedene Verwendungsszenarien .

Der Hauptzweck dieser Header-Datei besteht darin, ein Makro zu definieren: MY_API , und dieses Makro dann zur Deklaration jeder Funktion oder Klasse hinzuzufügen, die in die Bibliotheksdatei exportiert werden muss . Z.B:

void MY_API do_work();

Hier ist die Header-Datei:

_Pragma("once")

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
    #define MY_WIN32
#elif defined(linux) || defined(__linux) || defined(__linux__)
    #define MY_LINUX
#endif

#if defined(MY_WIN32)
    #ifdef MY_API_STATIC
      #ifdef __cplusplus
         #define MY_API extern "C"
      #else
         #define MY_API
      #endif
   #else
      #ifdef MY_API_EXPORTS
         #ifdef __cplusplus
            #define MY_API extern "C" __declspec(dllexport)
         #else
            #define MY_API __declspec(dllexport)
         #endif
      #else
         #ifdef __cplusplus
            #define MY_API extern "C" __declspec(dllimport)
         #else
            #define MY_API __declspec(dllimport)
         #endif
      #endif
   #endif
#elif defined(MY_LINUX)
    #ifdef __cplusplus
       #define MY_API extern "C"
    #else
       #define MY_API
    #endif
#endif

Drei, das vordefinierte Makro

Angenommen, Sie müssen eine Bibliotheksdatei schreiben und für andere bereitstellen. Nach der Definition des oben, das erste Dokument, andere Dokumente müssen enthalten diese Headerdatei.

1. Plattformmakrodefinition

Verschiedene Plattformen haben entsprechende Makrodefinitionen vordefiniert, zum Beispiel:

Windows-Plattform: WIN32, _WIN32, WIN32 ;
Linux-Plattform: Linux, __linux, Linux ;

Auf einer bestimmten Plattform sind möglicherweise nicht alle diese Makros definiert. Möglicherweise ist nur eines davon definiert.

Aus Gründen der Einheitlichkeit vereinheitlichen wir diese möglichen Makros am Anfang der Header-Datei und definieren unsere eigene Plattformmakrodefinition: MY_WIN32 oder MY_LINUX. Wenn wir später zwischen verschiedenen Plattformen unterscheiden müssen, verwenden wir dieses selbst definierte Plattformmakro .

Natürlich können Sie auch andere Plattformen wie MY_MAC, MY_ARM usw. weiter ausbauen.

2. Compiler-Makrodefinition

Wenn Sie beim Schreiben des Bibliothekscodes C ++ verwenden und der Benutzer die Sprache C verwendet, müssen Sie eine externe "C" -Deklaration für die Bibliotheksfunktion erstellen , damit der Compiler den Namen der Funktion nicht neu schreibt .

Das vom Compiler g ++ vordefinierte Makro verwendet __cplusplusdaher in der Header-Datei dieses Makro, MY_APIum die externe Anweisung "C" hinzuzufügen .

Viertens Windows-Plattform-Szenario-Analyse

1. Kompilieren und generieren Sie Bibliotheksdateien

(1) Generische statische Bibliothek generieren

In der statischen Bibliothek, keine __declspec(dllexport/dllimport)Anweisung, ist es nur erforderlich, Compiler (gcc oder g ++) zu unterscheiden, die Makro-Compiler-Optionen zu definieren MY_API_STATIC, können Sie die endgültigen MY_APIerhalten:

gcc compiler: #define MY_API
g ++ compiler: #define MY_API extern "C"

(2) Generieren Sie eine dynamische Bibliothek

Definieren Sie beim Kompilieren von Optionen Makros MY_API_EXPORTS, sodass das Ergebnis wie MY_APIfolgt lautet:

gcc-Compiler: #define MY_API __declspec (dllexport)
g ++ - Compiler: #define MY_API extern "C" __declspec (dllexport)

2. Verwenden der Bibliothek

In Benutzung der Bibliothek Anwendung, auch müssen Sie diesen Code in der Header - Datei schließen, und dann eine Vielzahl von Makro - Compiler - Optionen hinzuzufügen definiert, die entsprechend zu erzeugen MY_APIMakrodefinitionen.

(1) Verwenden Sie eine statische Bibliothek

Müssen bei Kompilierungsoptionen definiert werden MY_API_STATIC, können Sie die endgültigen MY_APIerhalten:

gcc compiler: #define MY_API
g ++ compiler: #define MY_API extern "C"

(2) Verwenden Sie eine dynamische Bibliothek

Benötigt kein Makro, das bei den Kompilierungsoptionen definiert wurde, können Sie die endgültigen MY_APIerhalten:

gcc-Compiler: #define MY_API extern "C" __declspec (dllimport)
g ++ - Compiler: #define MY_API __declspec (dllimport)

Dies entspricht der Deklaration der Importbibliotheksfunktion .

Fünftens: Analyse der Linux-Plattformszenarien

Unter der Linux-Plattform ist es viel einfacher, Sie müssen nur auf das Problem des Compilers achten, und es gibt keinen Unterschied zwischen Exportieren und Importieren.


Gute Artikel sollten weitergeleitet werden : Je mehr Sie teilen, desto mehr Glück haben Sie!


Literatur-Empfehlungen

1. C-Sprachzeiger - vom Prinzip der unteren Ebene bis hin zu ausgefallenen Fähigkeiten. Verwenden Sie Grafiken und Code, um eine gründliche Erklärung zu erhalten.
2. Das ursprüngliche Debugging-Prinzip der unteren Ebene von GDB ist so einfach.
3. Schritt-für-Schritt-Analyse - Verwendung von C bis objektorientierte Programmierung implementieren
4. Alles gesagt Die Softwarearchitektur muss geschichtet und in Module unterteilt werden, und was speziell getan werden sollte (1)
5. Es wird gesagt, dass die Softwarearchitektur geschichtet und in Module unterteilt werden muss und was sollte speziell durchgeführt werden (2)

Ich denke du magst

Origin blog.csdn.net/u012296253/article/details/115366952
Empfohlen
Rangfolge