自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

C語言邊角料5:一個跨平臺的頭文件

開發(fā) 后端
這篇短文分享一個頭文件,利用這個頭文件,再加上幾個編譯期間傳遞的宏,就可以完美的處理剛才所說的各種需求。

[[390476]]

一、前言

我們平常在寫代碼的時候,特別是在制造輪子的時候(為別人提供庫文件),會遇到各種不同的需求場景:

  1. 有些人需要在 Linux 系統(tǒng)下使用,有些人需要在 Windows 系統(tǒng)下使用;
  2. 有些人使用 C 語言開發(fā),有些人使用 C++ 來開發(fā);
  3. 有些人使用動態(tài)庫,有些人使用靜態(tài)庫;

特別是在 Windows 系統(tǒng)中,庫文件中導(dǎo)出的函數(shù)需要使用 _declspec(dllexport) 來聲明函數(shù),而使用者在導(dǎo)入的時候,需要使用 _declspec(dllimport) 來聲明函數(shù),甚是麻煩!

這篇短文分享一個頭文件,利用這個頭文件,再加上幾個編譯期間傳遞的宏,就可以完美的處理剛才所說的各種需求。

二、頭文件

先直接上代碼,可以先試著分析一下,后面我們再逐一分析不同的使用場景。

這個頭文件的主要目的,就是定義一個宏:MY_API,然后把這個宏添加在庫文件中每一個需要導(dǎo)出的函數(shù)或者類的聲明中即可。例如:

  1. void MY_API do_work(); 

下面是頭文件:

  1. _Pragma("once"
  2.  
  3. #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) 
  4.     #define MY_WIN32 
  5. #elif defined(linux) || defined(__linux) || defined(__linux__) 
  6.     #define MY_LINUX 
  7. #endif 
  8.  
  9. #if defined(MY_WIN32) 
  10.     #ifdef MY_API_STATIC 
  11.       #ifdef __cplusplus 
  12.          #define MY_API extern "C" 
  13.       #else 
  14.          #define MY_API 
  15.       #endif 
  16.    #else 
  17.       #ifdef MY_API_EXPORTS 
  18.          #ifdef __cplusplus 
  19.             #define MY_API extern "C" __declspec(dllexport) 
  20.          #else 
  21.             #define MY_API __declspec(dllexport) 
  22.          #endif 
  23.       #else 
  24.          #ifdef __cplusplus 
  25.             #define MY_API extern "C" __declspec(dllimport) 
  26.          #else 
  27.             #define MY_API __declspec(dllimport) 
  28.          #endif 
  29.       #endif 
  30.    #endif 
  31. #elif defined(MY_LINUX) 
  32.     #ifdef __cplusplus 
  33.        #define MY_API extern "C" 
  34.     #else 
  35.        #define MY_API 
  36.     #endif 
  37. #endif 

三、預(yù)定義的宏

假設(shè)需要寫一個庫文件,提供給別人使用。定義了上面這個頭文件之后,其他的文件中都要include 這個頭文件。

1. 平臺宏定義

不同的平臺預(yù)定義了相應(yīng)的宏定義,例如:

  • Windows 平臺:WIN32, _WIN32, WIN32;
  • Linux 平臺:linux, __linux, linux;

在一個確定的平臺上,這些宏不一定全部定義,很可能只有其中的某一個宏是被定義的。

為了統(tǒng)一性,我們在頭文件的剛開始部分,把這些可能的宏統(tǒng)一起來,定義我們出我們自己的平臺宏定義:MY_WIN32 或者是 MY_LINUX,后面需要區(qū)分不同的平臺時,就用這個自己定義的平臺宏。

當(dāng)然,還可以繼續(xù)擴(kuò)充出其他平臺,例如:MY_MAC, MY_ARM 等等。

2. 編譯器宏定義

如果在寫庫代碼的時候,使用的是 C++,而使用者使用的是 C 語言,那么就需要對庫函數(shù)進(jìn)行extern “C” 聲明,讓編譯器不要對函數(shù)的名稱進(jìn)行改寫。

編譯器 g++ 預(yù)定義了宏 __cplusplus,因此,在頭文件中,就利用了這個宏,在 MY_API 中添加 extern "C" 聲明。

四、Windows 平臺場景分析

1. 編譯生成庫文件

(1) 生成靜態(tài)庫

在靜態(tài)庫中,不需要 __declspec(dllexport/dllimport) 的聲明,因此只需要區(qū)分編譯器即可(gcc or g++),在編譯選項中定義宏 MY_API_STATIC,即可得到最終的 MY_API 為:

  • gcc 編譯器:#define MY_API
  • g++ 編譯器:#define MY_API extern "C"

(2) 生成動態(tài)庫

在編譯選項中,定義宏 MY_API_EXPORTS,這樣最終得到的 MY_API 就會變成:

  • gcc 編譯器:#define MY_API __declspec(dllexport)
  • g++ 編譯器:#define MY_API extern "C" __declspec(dllexport)

2. 使用庫

在使用庫的應(yīng)用程序中,也需要在代碼中 include 這個頭文件,然后加上編譯選項中定義的各種宏,來生成對應(yīng)的 MY_API 宏定義。

(1) 使用靜態(tài)庫

需要在編譯選項中定義 MY_API_STATIC,即可得到最終的 MY_API 為:

  • gcc 編譯器:#define MY_API
  • g++ 編譯器:#define MY_API extern "C"

(2) 使用動態(tài)庫

在編譯選項中不需要任何宏定義,即可得到最終的 MY_API 為:

  • gcc 編譯器:#define MY_API extern "C" __declspec(dllimport)
  • g++ 編譯器:#define MY_API __declspec(dllimport)

這樣就相當(dāng)于聲明導(dǎo)入庫函數(shù)了。

 

五、Linux 平臺場景分析

Linux 平臺下就簡單多了,只需要注意編譯器的問題,而沒有導(dǎo)出和導(dǎo)入之分。

 

責(zé)任編輯:姜華 來源: IOT物聯(lián)網(wǎng)小鎮(zhèn)
相關(guān)推薦

2021-03-26 11:29:58

C語言PragmaAPI

2021-03-22 11:27:06

C語言Peterson(皮特互斥鎖

2021-03-24 08:02:58

C語言

2021-05-11 11:31:52

C語言類型指針

2010-01-19 15:18:12

C++語言

2014-03-12 10:00:26

移動開發(fā)跨平臺

2012-06-27 17:30:03

VisionMobil跨平臺開發(fā)工具

2021-02-01 17:29:19

FlutterHello World開發(fā)

2015-03-17 09:59:41

跨平臺

2021-06-23 06:12:38

Subtitld編輯器開源

2015-06-30 08:37:12

ASP.NET.NET

2023-12-07 12:59:46

C語言循環(huán)隊列代碼

2021-11-15 14:42:20

Motrix下載管理器開源

2022-11-21 07:57:56

cmake工程模板

2021-01-14 08:55:20

C語言編程

2018-11-09 09:40:52

2013-05-27 09:47:33

Java開發(fā)Java跨平臺

2010-01-25 17:55:38

C++頭文件

2023-02-26 23:49:17

Go語言監(jiān)聽庫

2009-07-31 17:14:19

C#語言Web程序
點贊
收藏

51CTO技術(shù)棧公眾號