+---------------------------+
| 平台無關業務邏輯 (main) | ← 只調用跨平台介面
+---------------------------+
| 跨平台抽象層 (platform) | ← 統一介面聲明
+---------------------------+
| Win32 實現 | Linux 實現 | ← 各平台具體實現
+---------------------------+
platform.hpp
// platform.hpp
#pragma once
#include <string>
using handle_t = void*; // 不透明句柄
handle_t my_load_library(const std::string& name);
void my_free_library(handle_t h);
void* my_get_symbol(handle_t h, const char* sym);
// win32_platform.cpp
#include "platform.hpp"
#include <windows.h>
handle_t my_load_library(const std::string& name) {
return LoadLibraryA(name.c_str());
}
void my_free_library(handle_t h) { FreeLibrary((HMODULE)h); }
void* my_get_symbol(handle_t h, const char* sym) {
return GetProcAddress((HMODULE)h, sym);
}
// linux_platform.cpp
#include "platform.hpp"
#include <dlfcn.h>
handle_t my_load_library(const std::string& name) {
return dlopen(name.c_str(), RTLD_LAZY);
}
void my_free_library(handle_t h) { dlclose(h); }
void* my_get_symbol(handle_t h, const char* sym) {
return dlsym(h, sym);
}
# CMakeLists.txt
if(WIN32)
set(PLATFORM_SRC win32_platform.cpp)
elseif(UNIX)
set(PLATFORM_SRC linux_platform.cpp)
endif()
add_library(platform ${PLATFORM_SRC})
target_link_libraries(main PRIVATE platform)
或用 Makefile:include buildenv/$(OS).inc 覆蓋編譯器/標誌。
| 類別 | 注意點 |
|---|---|
| 文件路徑 | 用 boost::filesystem 或 std::filesystem (C++17) 抽象分隔符 |
| 大小寫敏感 | Linux 區分,Windows 不區分,資源載入統一小寫 |
| 字節序 | 網絡傳輸用 htonl/ntohl,文件存儲固定大端 |
| 對齊 | ARM 等架構不對齊會 SIGBUS,用 memcpy 而非強轉指標 |
| 類型大小 | 用 int32_t 等固定寬度類型,避免 long 32/64 差異 |
| 符號可見性 | Windows 需 __declspec(dllexport),Linux 預設導出,用宏統一 |
| 換行符 | 文本模式 fopen 自動轉換,二進制模式保持原樣 |
__declspec),必要時用宏隔離。strdup, alloca, snprintf 早期不標準),或自行實現兼容層。pkg-config 或 find_package 鎖定版本。移植性本質是**依賴倒置**:業務依賴抽象,抽象不依賴具體。前期投入封裝層,後期新增平台只需實現一組介面,主邏輯零修改。良好的邏輯/物理設計是前提——高內聚、低耦合的代碼天然易移植。