一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C/C++ - C語言邊角料5:一個跨平臺的頭文件

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

2021-03-31 23:31IOT物聯網小鎮道哥 C/C++

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

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

一、前言

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

  1. 有些人需要在 Linux 系統下使用,有些人需要在 Windows 系統下使用;
  2. 有些人使用 C 語言開發,有些人使用 C++ 來開發;
  3. 有些人使用動態庫,有些人使用靜態庫;

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

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

二、頭文件

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

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

  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 

三、預定義的宏

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

1. 平臺宏定義

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

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

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

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

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

2. 編譯器宏定義

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

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

四、Windows 平臺場景分析

1. 編譯生成庫文件

(1) 生成靜態庫

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

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

(2) 生成動態庫

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

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

2. 使用庫

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

(1) 使用靜態庫

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

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

(2) 使用動態庫

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

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

這樣就相當于聲明導入庫函數了。

五、Linux 平臺場景分析

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

原文地址:https://mp.weixin.qq.com/s/N6Ome9vs9OEocqdWv-MfEw

延伸 · 閱讀

精彩推薦
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數使用

    詳解c語言中的 strcpy和strncpy字符串函數使用

    strcpy 和strcnpy函數是字符串復制函數。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內存中的數據都是暫時的,當程序結束時,它們都將丟失,為了永久性的保存大量的數據,C語言提供了對文件的操作,這篇文章主要給大家介紹了關于C語言中文件...

    針眼_6702022-01-24
  • C/C++學習C++編程的必備軟件

    學習C++編程的必備軟件

    本文給大家分享的是作者在學習使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++深入理解goto語句的替代實現方式分析

    深入理解goto語句的替代實現方式分析

    本篇文章是對goto語句的替代實現方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網7342020-12-03
  • C/C++c++ 單線程實現同時監聽多個端口

    c++ 單線程實現同時監聽多個端口

    這篇文章主要介紹了c++ 單線程實現同時監聽多個端口的方法,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++C/C++經典實例之模擬計算器示例代碼

    C/C++經典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關于C/C++經典實例之模擬計算器的相關資料,文中通過示...

    jia150610152021-06-07
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++C語言實現電腦關機程序

    C語言實現電腦關機程序

    這篇文章主要為大家詳細介紹了C語言實現電腦關機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
主站蜘蛛池模板: blacked亚裔videoshd | 好大好硬好深好爽gif图 | 免费网址在线观看入口推荐 | 国产普通话对白露脸流出 | 冰漪丰满大乳人体图片欣赏 | 欧美国产日本精品一区二区三区 | 亚洲免费福利视频 | 奇米影视亚洲狠狠色 | 学校女性奴sm训练调教 | 双性总裁被调教1v1 双性双根 | 91香蕉小视频 | 成人影院入口 | 国产高清在线看 | 男生同性啪视频在线观看 | 久久免费观看视频 | 成年美女黄网色大观看全 | 精品日韩欧美一区二区三区 | 韩国男女做性全过程视频 | 午夜a一级毛片 | 继的朋友无遮漫画免费观看73 | 甜蜜调教 | 国产精品激情综合久久 | 青青草综合网 | 亚洲狠狠婷婷综合久久蜜桃 | 日本免费久久久久久久网站 | 精品久久免费观看 | 茄子视频懂你更多apl | 午夜一个人在线观看完整版 | 色综合图片 | 特黄视频免费看 | 亚洲天堂2016 | 极品丝袜乱系列在线阅读 | 国产精品第1页在线播放 | 天色综合| 9191精品国产观看 | 亚洲一区二区三区不卡在线播放 | 人皮高跟鞋在线观看 | 男人影院在线观看 | 九九精品视频在线免费观看 | 天美传媒tm0065 | 欧美精品v日韩精品v国产精品 |