將 Win32 程式移植到 Linux

ztguang發表於2016-02-01

http://blog.csdn.net/ithomer/article/details/6271572


對於這個問題,網上已經有很多資料給予了介紹,但是相比於這些資訊,本文立足於個人的實踐,將內容具體到開發環境和原始碼,我覺得還是有很多值得總結和借鑑的。

首先宣告開發環境。Win32程式的開發環境是VS.Net 2008,程式語言是C;Linux使用的RHEL 5.4,GCC的版本是4.1.2,程式語言也是C。

然後依次說明移植的物件:資料型別/字串處理/系統呼叫/套接字/程式/程式鎖/執行緒/執行緒鎖/訊號量/事件鎖/條件鎖/系統服務。

1. 資料型別:在開發過程中,無論哪種平臺,只使用最通用的資料型別char,unsigned char,int,unsigned int,void *以及它們組合的結構體型別。對於資料長度敏感的程式碼,則只使用下面的資料型別:


Common

Win32

Linux

int8

INT8

int8_t

uint8

UINT8

uint8_t

int16

INT16

int16_t

uint16

UINT16

uint16_t

int32

INT32

int32_t

uint32

UINT32

uint32_t

int64

INT64

int64_t

uint64

UINT64

uint64_t

在VS.Net 2008的專案中,使用多位元組字符集,對於需要寬字元的系統呼叫,使用位元組轉換函式來處理引數。

2. 字串處理:雖然每個函式在兩個平臺下都有對應的實現,但是最好自己重新實現,因為它們都不足夠令人滿意:


Common

Win32

Linux

stricmp_x

_stricmp

strcasecmp

strtok_x

strtok_s

strtok_r

sprintf_x

sprintf_s

snprintf

vsprintf_x

vsprintf_s

vsnprintf

strcpy_x

strcpy_s

strncpy

strcat_x

strcat_s

strncat

3. 系統呼叫:真正的系統呼叫雖然不多,只有僅有的幾十個,但有些系統呼叫差別很大,這裡就不便做一一贅述了,而有些系統呼叫基本沒有差別,比如檔案相關的操作。

4. 套接字:套 接字的幾個主要函式都一樣,socket/bind/listen/connect/accept/select/send/recv,幾個細微的差別在 於Win32使用套接字執行TCP/IP協議需要初始化上下文環境,另外,對於套接字定義,Win32使用SOCKET,Linux使用int,對於關閉 套接字,Win32使用closesocket,Linux使用close。

5. 程式:在 Windows平臺中使用CreateProcess來建立程式,子程式返回控制程式碼和ID給父程式,在Linux平臺中使用fork和execv來建立進 程,子程式返回ID給父程式。兩者最大的差別在於,在Windows平臺中子程式跟父程式沒有任何關係,而在Linux平臺中,子程式繼承了父程式的程式 上下文環境。其它相關函式的差別如下:


Win32

Linux

CreateProcess

fork/execv

TerminateProcess

kill

ExitProcess

exit

GetCommandLine

argv

GetCurrentProcessId

getpid

KillTimer

alarm

SetEnvironmentVariable

putenv

GetEnvironmentVariable

getenv

GetExitCodeProcess

waitpid

6. 程式鎖:是 指多個程式同步的機制。多程式同步的方法有很多,比如共享記憶體,命名訊號量等。這裡只說明一下命名訊號量的機制,共享記憶體的方法可以查閱相關手冊。 Win32比較簡單,在CreateMutex的引數中輸入相應名稱即可,Linux中,則可使用System V IPC的semget/semctl/semop操作,具體步驟直接man之。

7. 執行緒:執行緒同步、等待函式、執行緒本地儲存以及初始化和終止抽象是執行緒模型的重要部分。主要對應函式列表如下:


Win32

Linux

_beginthreadex

pthread_create

_endthreadex

pthread_exit

TerminateThread

pthread_cancel

GetCurrentThreadId

pthread_self

8. 執行緒鎖:對應函式列表如下。另外,特別注意的是,Win32的mutex在預設情況下是可以遞迴加鎖和解鎖的,但是pthread的mutex在預設情況下則不能,需要在pthread_mutex_init時設定pthread_mutexattr_t引數。


Win32

Linux

CreateMutex

pthread_mutex_init

CloseHandle

pthread_mutex_destroy

WaitForSingleObject

pthread_mutex_lock

ReleaseMutex

pthread_mutex_unlock

9. 訊號量/事件鎖/條件鎖:這 三個同步機制功能比較相似,甚至可以相互實現。除了這三種同步機制外,各個平臺上還有一些專有的同步機制。Windows平臺上有訊號量和事件鎖,但是沒 有條件鎖,直到Windows 2008 Server上才會有。Linux平臺上有訊號量和條件鎖,但是沒有事件鎖。在一些特定場合下,沒有的同步機制只能通過已有的同步機制去實現:


Common

Win32

Linux

Semaphore

CreateSemaphore

pthread_mutex_init 
pthread_cond_init 
(implement) 
or sem_init

Event

CreateEvent

pthread_mutex_init 
(implement)

Condition

CreateSemaphore 
(implement)

pthread_cond_init

10. 系統服務:在 Windows中,系統服務叫service,可以通過管理工具,或者執行services.msc進入管理介面,可以安裝,解除安裝,啟動,停止和重啟。在 Linux中,系統服務叫daemon,一般通過命令service ??? start/stop/restart來啟動,停止和重啟,同樣也可以安裝和解除安裝。Windows服務可以通過SCM(Service Control Management)架構來實現,Linux服務則需要編寫chkconfig相關的指令碼來實現。注意,不同的Linux發行版,比如RHEL和 SLES,實現指令碼是不一樣的。


<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
閱讀(131) | 評論(0) | 轉發(0) |
給主人留下些什麼吧!~~
評論熱議

相關文章