成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

詳解跨平臺代碼的3種組織方式

開發
我們在源代碼中也會遇到一些跨平臺的問題。不同的功能,在不同的平臺下,實現方式是不一樣的,如何對這些平臺相關的代碼進行組織呢?這篇文章就來聊聊這個問題。

[[390799]]

一、緣起

在上一篇文章中,分享了一個跨平臺的頭文件是長成什么樣子的,這個頭文件對于 windows 平臺下更有意義一些,因為要處理庫函數的導入和導出聲明(dllexport、dllimport)。

其實,可以在這個頭文件的基礎上繼續擴充,以達到更細粒度的控制。例如:對編譯器的判斷、對編譯器版本的判斷等等。

同樣的,我們在源代碼中也會遇到一些跨平臺的問題。不同的功能,在不同的平臺下,實現方式是不一樣的,如何對這些平臺相關的代碼進行組織呢?這篇文章就來聊聊這個問題。

PS: 文末提供了一個簡單的、跨平臺構建代碼示例。

二、問題引入

假設我們寫一個庫,需要實現一個函數:獲取系統時間戳。作為實現庫的作者,你決定提供下面的 API 函數:

  1. t_time.h: 聲明接口函數(t_get_timestamp); 
  2. t_time.c:實現接口函數; 

下面的任務就是在函數實現中,通過不同下的 C 庫或系統調用,來計算系統當前的時間戳。

在 Linux 平臺下,可以通過下面這段代碼實現:

  1. struct timeval tv; 
  2. gettimeofday(&tv, null); 
  3. return tv.tv_sec * 1000 + tv.tv_usec / 1000; 

在 Windows 平臺下,可以通過下面這段代碼實現:

  1. struct timeb tp; 
  2. ftime(&tp); 
  3. return tp.time *1000 + tp.millitm; 

那么問題來了:怎么把這兩段平臺相關的代碼組織在一起?下面就介紹 3 種不同的組織方式,沒有優劣之分,每個人都有不同的習慣,選擇適合自己和團隊的方式就行。

此外,這個示例中只有 1 個函數,而且比較短小。如果這種跨平臺的函數很多、而且都很長,也許你的選擇又不一樣了。

三、三個解決方案

方案1

直接在接口函數中,通過平臺宏定義來區分不同平臺。

平臺宏定義(T_LINUX, T_WINDOWS),是在上一篇文章中介紹的,通過操作系統、編譯器來判斷當前的平臺是什么,然后定義出統一的平臺宏定義為我們自己所用:

代碼組織方式如下:

  1. int64 t_get_timestamp() 
  2.     int64 ts = -1; 
  3.      
  4. #if defined(T_LINUX) 
  5.     struct timeval tv; 
  6.     gettimeofday(&tv, null); 
  7.     ts = tv.tv_sec * 1000 + tv.tv_usec / 1000; 
  8. #elif defined(T_WINDOWS) 
  9.     struct timeb tp; 
  10.     ftime(&tp); 
  11.     ts = tp.time
  12.     ts = ts *1000 + tp.millitm; 
  13. #endif 
  14.  
  15.     return ts; 

這樣的方式,把所有平臺代碼全部放在 API 函數中了,通過平臺宏定義進行條件編譯,因為代碼比較短小,看起來還不錯。

方案2

把不同平臺的實現代碼放在獨立的文件中,然后通過 #include 預處理符號,在 API 函數中,把平臺相關的代碼引入進來。

也就是再增加 2 個文件:

  1. t_time_linux.c:存放 Linux 平臺下的代碼實現; 
  2. t_time_windows.c:存放 Windows 平臺下的代碼實現; 

(1) t_time_linux.c

  1. #include "t_time.h" 
  2. #include <sys/time.h> 
  3.  
  4. int64 t_get_timestamp() 
  5.     int64 ts = -1; 
  6.      
  7.     struct timeval tv; 
  8.     gettimeofday(&tv, null); 
  9.     ts = tv.tv_sec * 1000 + tv.tv_usec / 1000; 
  10.      
  11.     return ts; 

(2) t_time_windows.c

  1. #include "t_time.h" 
  2. #include <windows.h> 
  3. #include <sys/timeb.h> 
  4.  
  5. int64 t_get_timestamp() 
  6.     int64 ts = -1; 
  7.      
  8.     struct timeb tp; 
  9.     ftime(&tp); 
  10.     ts = tp.time
  11.     ts = ts *1000 + tp.millitm; 
  12.  
  13.     return ts; 

(3) t_time.c

這個文件不做任何事情,僅僅是 include 其他的代碼。

  1. #include "t_time.h" 
  2.  
  3. #if defined(T_LINUX) 
  4. #include <t_time_linux.c> 
  5. #elif defined(T_WINDOWS) 
  6. #include <t_time_windows.c> 
  7. #else 
  8. int64 t_get_timestamp() 
  9.     return -1; 
  10. #endif 

有些人比較反感這樣的組織方式,一般都是 include 一個 .h 頭文件,而這里通過平臺宏定義,include 不同的 .c 源文件,感覺怪怪的?!

其實,也有一些開源庫是這么干的,比如下面:

方案3

在上面方案2中,是在源代碼中填入不同平臺的實現代碼。

其實可以換一種思路,既然已經根據平臺的不同、放在不同的文件中了,那么可以讓不同的源文件加入到編譯過程中就可以了。

測試代碼是使用 cmake 工具來構建的,因此可以編輯 CMakelists.txt 文件,來控制參與編譯的源文件。

CMakelists.txt 文件部分內容

  1. # 設置平臺變量 
  2. if (CMAKE_SYSTEM_NAME MATCHES "Linux"
  3. set(PLATFORM linux) 
  4. elseif (CMAKE_SYSTEM_NAME MATCHES "Windows"
  5. set(PLATFORM windows) 
  6. endif() 
  7.  
  8. # 根據平臺變量,來編譯不同的源文件 
  9. set(LIBSRC  t_time_${PLATFORM}.c) 

這樣的組織方式,感覺代碼更“干凈”一些。同樣的,我們也可以看到一些開源庫也是這么做的:

四、One More Thing

為了文章的篇幅,以上只是貼了代碼的片段。

我寫了一個最簡單的 demo,使用 cmake 來構建跨平臺的動態庫、靜態庫、可執行程序。寫這個 demo 的目的,主要是作為一個外殼,來測試一些寫文章時的代碼。

在 Linux 平臺下,通過 cmake 指令手動編譯;在 Windows 平臺下,可以通過 CLion 集成開發環境直接編譯、執行,也可以通過 cmake 工具直接生成 VS2017/2019 解決方案。

已經把這個 demo 放在 gitee 倉庫中了,感興趣的小伙伴,請在公眾號回復:dg36,即可收到克隆地址。

 

責任編輯:姜華 來源: IOT物聯網小鎮
相關推薦

2012-07-06 15:00:03

跨平臺工具MoSync

2012-07-06 15:08:14

跨平臺工具Netbiscuits

2012-07-06 15:03:43

跨平臺工具Ideaworks 3Marmalade

2012-06-14 09:48:06

跨平臺工具SeregonDragonRad

2012-07-06 14:02:25

跨平臺工具RunRevLiveCode

2012-07-06 13:50:44

跨平臺工具Adobe Phone

2012-07-06 15:10:39

跨平臺工具QtNokia

2012-06-14 09:57:12

跨平臺工具IBMWorklight

2012-06-14 09:42:20

跨平臺工具AppceleratoTitanium

2020-02-18 20:00:31

PostgreSQL數據庫

2024-11-11 08:00:00

2012-07-06 14:56:38

跨平臺工具Motorola SoRhoMobile

2012-06-14 09:37:17

Ansca MobilCorona跨平臺工具

2012-07-06 13:45:21

跨平臺工具Adobe AirFlex

2017-09-05 10:20:15

2020-02-10 15:50:18

Spring循環依賴Java

2010-02-01 10:43:10

C++跨平臺應用

2011-07-08 20:54:12

iPhone WCF

2013-05-23 09:49:28

虛擬化桌面虛擬化

2019-05-29 19:00:35

HTML5存儲方式前端
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 青青伊人久久 | 亚洲一区久久 | 精品一区二区免费视频 | 成人亚洲精品久久久久软件 | 97国产在线视频 | 欧美 日韩精品 | 北条麻妃一区二区三区在线视频 | 国产一区欧美 | 欧美日韩国产精品一区 | 欧美激情99| 国产精品中文字幕在线观看 | 国产真实精品久久二三区 | 国产网站在线播放 | www.亚洲免费 | 国产第一区二区 | 羞羞色影院| 国产女人精品视频 | 日韩一区二区在线视频 | 夜夜爽99久久国产综合精品女不卡 | 日本精品一区二区三区在线观看视频 | 亚洲精品一区二区在线 | 日韩www| 久久国产精品亚洲 | 国产91丝袜在线熟 | 久国久产久精永久网页 | 久久一本| 亚洲精品日韩一区二区电影 | 日韩有码一区 | 久久国产精品一区二区三区 | 成人免费观看视频 | 中文字幕av亚洲精品一部二部 | 美女131mm久久爽爽免费 | 久久久久久国产精品三区 | 农村真人裸体丰满少妇毛片 | 国产欧美一区二区三区久久手机版 | 亚洲精品久久久久久下一站 | 可以在线观看av的网站 | 91精品国产91久久久久久 | 九九导航 | 九九精品在线 | 国产精品不卡视频 |