平台子系统(CategoryPlatform)
SDL 提供了在编译期和运行期识别应用程序运行平台的方法,帮助开发者实现跨平台的差异化逻辑处理。
函数
- SDL_GetPlatform:运行时获取当前平台名称(返回字符串指针,如 "Windows"、"Linux"、"macOS" 等,无需手动释放)
数据类型
- (无)
结构体
- (无)
枚举
- (无)
宏
- SDL_PLATFORM_3DS:编译期宏,标识任天堂 3DS 平台
- SDL_PLATFORM_AIX:编译期宏,标识 IBM AIX 系统
- SDL_PLATFORM_ANDROID:编译期宏,标识 Android 平台
- SDL_PLATFORM_APPLE:编译期宏,标识苹果系平台(包含 macOS/iOS/tvOS 等)
- SDL_PLATFORM_BSDI:编译期宏,标识 BSDI 系统
- SDL_PLATFORM_CYGWIN:编译期宏,标识 Cygwin 环境(Windows 下的类 Unix 层)
- SDL_PLATFORM_EMSCRIPTEN:编译期宏,标识 Emscripten 编译的 WASM/HTML5 平台
- SDL_PLATFORM_FREEBSD:编译期宏,标识 FreeBSD 系统
- SDL_PLATFORM_GDK:编译期宏,标识 Xbox GDK 开发套件平台
- SDL_PLATFORM_HAIKU:编译期宏,标识 Haiku 操作系统
- SDL_PLATFORM_HPUX:编译期宏,标识 HP-UX 系统
- SDL_PLATFORM_HURD:编译期宏,标识 GNU Hurd 系统
- SDL_PLATFORM_IOS:编译期宏,标识 iOS 平台
- SDL_PLATFORM_IRIX:编译期宏,标识 SGI IRIX 系统
- SDL_PLATFORM_LINUX:编译期宏,标识 Linux 系统
- SDL_PLATFORM_MACOS:编译期宏,标识 macOS 系统
- SDL_PLATFORM_NETBSD:编译期宏,标识 NetBSD 系统
- SDL_PLATFORM_NGAGE:编译期宏,标识诺基亚 N-Gage 平台
- SDL_PLATFORM_OPENBSD:编译期宏,标识 OpenBSD 系统
- SDL_PLATFORM_OS2:编译期宏,标识 OS/2 系统
- SDL_PLATFORM_OSF:编译期宏,标识 OSF/1 系统
- SDL_PLATFORM_PS2:编译期宏,标识索尼 PS2 平台
- SDL_PLATFORM_PSP:编译期宏,标识索尼 PSP 平台
- SDL_PLATFORM_QNXNTO:编译期宏,标识 QNX Neutrino 系统
- SDL_PLATFORM_RISCOS:编译期宏,标识 RISC OS 系统
- SDL_PLATFORM_SOLARIS:编译期宏,标识 Solaris 系统
- SDL_PLATFORM_TVOS:编译期宏,标识 tvOS 平台(苹果电视)
- SDL_PLATFORM_UNIX:编译期宏,标识通用 Unix 类系统
- SDL_PLATFORM_VISIONOS:编译期宏,标识 visionOS 平台(苹果 Vision Pro)
- SDL_PLATFORM_VITA:编译期宏,标识索尼 PS Vita 平台
- SDL_PLATFORM_WIN32:编译期宏,标识 32/64 位 Windows 平台(兼容 Win32/Win64)
- SDL_PLATFORM_WINDOWS:编译期宏,标识 Windows 平台(与 SDL_PLATFORM_WIN32 等价)
- SDL_PLATFORM_WINGDK:编译期宏,标识 Windows GDK 平台
- SDL_PLATFORM_XBOXONE:编译期宏,标识 Xbox One 平台
- SDL_PLATFORM_XBOXSERIES:编译期宏,标识 Xbox Series X/S 平台
- SDL_WINAPI_FAMILY_PHONE:编译期宏,标识 Windows Phone 平台
FreeBASIC 示例代码
' 引入 SDL 相关声明(需确保 FreeBASIC 已链接 SDL3 库)
#Include "SDL.bi"
' 补充函数声明(FreeBASIC 绑定可能缺失)
Declare Function SDL_GetPlatform CDecl () As ZString Ptr
' 编译期平台判断示例(预处理指令)
#If Defined(SDL_PLATFORM_WINDOWS)
#Define PLATFORM_NAME "Windows"
#Elif Defined(SDL_PLATFORM_LINUX)
#Define PLATFORM_NAME "Linux"
#Elif Defined(SDL_PLATFORM_MACOS)
#Define PLATFORM_NAME "macOS"
#Elif Defined(SDL_PLATFORM_ANDROID)
#Define PLATFORM_NAME "Android"
#Elif Defined(SDL_PLATFORM_IOS)
#Define PLATFORM_NAME "iOS"
#Elif Defined(SDL_PLATFORM_EMSCRIPTEN)
#Define PLATFORM_NAME "Emscripten (WASM/HTML5)"
#Else
#Define PLATFORM_NAME "Unknown Platform"
#EndIf
' 运行期平台处理逻辑
Sub HandlePlatformSpecificLogic()
Dim As ZString Ptr runtimePlatform = SDL_GetPlatform()
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "运行期检测到平台:%s", *runtimePlatform)
' 根据运行期平台执行差异化逻辑
Select Case *runtimePlatform
Case "Windows"
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "执行 Windows 专属逻辑:适配注册表、路径分隔符为 \")
' 示例:Windows 下的文件路径处理、注册表访问等
Case "Linux"
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "执行 Linux 专属逻辑:适配 /home 目录、权限管理")
' 示例:Linux 下的系统配置文件读取、权限检查等
Case "Mac OS X", "macOS"
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "执行 macOS 专属逻辑:适配 ~/Library 目录、沙盒权限")
' 示例:macOS 下的应用沙盒、Finder 集成等
Case "Android"
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "执行 Android 专属逻辑:适配 APK 资源、JNI 调用")
' 示例:Android 下的权限申请、JNI 交互等
Case "iOS"
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "执行 iOS 专属逻辑:适配沙盒、应用内购买")
' 示例:iOS 下的沙盒文件访问、IAP 处理等
Case Else
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "未适配的平台:%s,使用通用逻辑", *runtimePlatform)
End Select
End Sub
' 主程序
Sub Main()
' 初始化 SDL
If (SDL_Init(0) < 0) Then
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL 初始化失败:%s", SDL_GetError())
Exit Sub
End If
' 打印编译期平台信息
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "编译期检测到平台:%s", PLATFORM_NAME)
' 执行运行期平台逻辑
HandlePlatformSpecificLogic()
' 清理 SDL
SDL_Quit()
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, vbCrLf & "程序正常退出")
End Sub
' 运行主程序
Main()
核心知识点补充
-
编译期 vs 运行期平台检测:
- *编译期宏(SDLPLATFORM)**:在代码编译时确定平台,用于条件编译(如不同平台的代码分支、头文件引入);
- 运行期函数(SDL_GetPlatform):程序运行时获取实际平台名称,适用于「同一编译产物运行在多平台」的场景(如跨平台打包的应用、Emscripten 编译的 WASM)。
-
SDL_GetPlatform 返回值规范: 平台 返回字符串 Windows(32/64位) "Windows" Linux "Linux" macOS "Mac OS X" / "macOS" Android "Android" iOS "iOS" Emscripten "Emscripten" FreeBSD "FreeBSD" Xbox "Xbox One" / "Xbox Series X/S" -
跨平台开发最佳实践:
- 编译期宏用于「不可变的平台差异」(如头文件、API 声明);
- 运行期检测用于「可变的运行环境」(如同一二进制包运行在不同 Linux 发行版);
- 优先使用 SDL 提供的跨平台 API 封装,减少直接的平台判断;
- 平台判断逻辑集中管理,避免散落在代码各处。
总结
-
核心优势:
- 同时支持编译期和运行期平台检测,覆盖不同跨平台开发场景;
- 统一的平台标识体系,避免开发者记忆不同平台的原生宏定义;
SDL_GetPlatform返回的字符串格式稳定,便于运行期逻辑判断;- 编译期宏覆盖主流平台(PC、移动端、游戏主机、嵌入式),满足多平台开发需求。
-
使用建议:
- 编译期:用
#If Defined(SDL_PLATFORM_XXX)做条件编译,隔离平台专属代码; - 运行期:用
SDL_GetPlatform()获取平台名称,执行差异化的运行逻辑; - 避免过度依赖平台判断,优先使用 SDL 封装的跨平台接口(如文件路径、输入输出);
- 对 SDL 未覆盖的小众平台,可结合原生宏(如
__linux__、_WIN32)补充判断。
- 编译期:用
-
关键点回顾:
SDL_GetPlatform()是运行期平台检测的核心函数,返回值无需手动释放;- 编译期宏(SDLPLATFORM*)用于条件编译,区分不同平台的编译逻辑;
- 跨平台开发应优先使用 SDL 封装的 API,仅在必要时做平台差异化处理。
评论一下?