www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當前位置:首頁 > 公眾號精選 > 滿天芯
[導讀]一、前言二、頭文件三、預定義的宏四、Windows平臺場景分析五、Linux平臺場景分析一、前言我們平常在寫代碼的時候,特別是在制造輪子的時候(為別人提供庫文件),會遇到各種不同的需求場景:有些人需要在Linux系統(tǒng)下使用,有些人需要在Windows系統(tǒng)下使用;有些人使用C語言開...


  • 一、前言


  • 二、頭文件


  • 三、預定義的宏


  • 四、Windows 平臺場景分析


  • 五、Linux 平臺場景分析



一、前言

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


  1. 有些人需要在 Linux 系統(tǒng)下使用,有些人需要在 Windows 系統(tǒng)下使用;
  2. 有些人使用 C 語言開發(fā),有些人使用 C 來開發(fā);
  3. 有些人使用動態(tài)庫,有些人使用靜態(tài)庫;
特別是在 Windows 系統(tǒng)中,庫文件中導出的函數(shù)需要使用 _declspec(dllexport) 來聲明函數(shù),而使用者在導入的時候,需要使用 _declspec(dllimport) 來聲明函數(shù),甚是麻煩!


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


二、頭文件

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


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


void MY_API do_work();
下面是頭文件:


_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

三、預定義的宏

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


1. 平臺宏定義

不同的平臺預定義了相應的宏定義,例如:


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


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


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


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


2. 編譯器宏定義

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


編譯器 g 預定義了宏__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. 使用庫

使用庫的應用程序中,也需要在代碼中 include 這個頭文件,然后加上編譯選項中定義的各種宏,來生成對應的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)


這樣就相當于聲明導入庫函數(shù)了。


五、Linux 平臺場景分析

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


好文章,要轉發(fā);越分享,越幸運!星標公眾號,能更快找到我!



本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。
關閉
關閉