跨平台移植 Windows C/C++ 程式碼至 Linux 時,Win32 API 與 C 執行階段庫的差異是主要阻礙。本文針對四個高頻問題提供可直接落地的替換實作。
GetTickCount():系統啟動毫秒數Windows 返回自系統啟動以來的毫秒數(32 位無號整數,約 49.7 天溢位)。Linux 使用 times() 取得時鐘嘀嗒數,需轉換為毫秒。
#include <sys/times.h>
#include <unistd.h>
long GetTickCount()
{
struct tms tm;
clock_t ticks = times(&tm); // 返回進程時間,非系統啟動時間
// 注意:times() 返回的是進程 CPU 時間,非牆鐘時間。
// 若需單調時鐘,建議使用 clock_gettime(CLOCK_MONOTONIC, ...)
return (long)(ticks * (1000 / sysconf(_SC_CLK_TCK)));
}
補充:生產環境建議改用 clock_gettime(CLOCK_MONOTONIC, &ts) 計算毫秒,精度更高且不受系統時間調整影響。
itoa():整數轉字串Linux 標準庫無 itoa,常用 sprintf 或 snprintf 替代。若既有程式碼大量呼叫 itoa,可提供相容實作:
#if defined(__linux__)
char* itoa(int value, char* str, int radix)
{
static const char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
char* p = str;
char* head = str;
int sign = 0;
if (radix == 10 && value < 0) { sign = 1; value = -value; }
do { *p++ = digits[value % radix]; value /= radix; } while (value);
if (sign) *p++ = '-';
*p = '\0';
// 反轉字串
for (--p; head < p; ++head, --p) { char tmp = *head; *head = *p; *p = tmp; }
return str;
}
#endif
此實作支援 2~36 進位,含負號處理,無需 STL 依賴。
_strrev() / strrev():字串反轉Linux 缺此函式,提供兩種實作:
#if defined(__linux__)
char* strrev(char* szT)
{
if (!szT) return "";
int len = strlen(szT);
for (int i = 0, j = len - 1; i < j; ++i, --j) {
char tmp = szT[i]; szT[i] = szT[j]; szT[j] = tmp;
}
return szT;
}
#endif
#if defined(__linux__)
#include <algorithm>
#include <cstring>
char* strrev(char* szT)
{
if (!szT) return "";
std::string s(szT);
std::reverse(s.begin(), s.end());
strcpy(szT, s.c_str());
return szT;
}
#endif
Sleep():執行緒休眠Windows Sleep(ms) 以毫秒為單位;Linux usleep(us) 以微秒為單位(已棄用),現代建議用 nanosleep。
#if defined(__linux__)
#include <time.h>
void Sleep(unsigned int milliseconds)
{
struct timespec req = {
.tv_sec = milliseconds / 1000,
.tv_nsec = (milliseconds % 1000) * 1000000L
};
nanosleep(&req, NULL);
}
#endif
使用 nanosleep 避免信號中斷導致提前返回,符合 POSIX 標準。
PlatformCompat.h/cpp),以條件編譯隔離。<chrono>, <thread>, std::to_string 等)。