將Win32程序移植到Linux上

原文: http://csynine.blog.51cto.com/1388509/310927

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

首先聲明開發環境。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,實現腳本是不一樣的。


發佈了2 篇原創文章 · 獲贊 4 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章