SDL3_API分类参考_区域设置(CategoryLocale)

2026-3-7 / 0 评论 / 2 阅读

区域设置子系统(CategoryLocale)

SDL 提供了轻量的区域设置服务,核心能力是获取用户的首选区域列表(由「语言 + 国家/地区」组成)。该子系统仅包含一个核心函数:SDL_GetPreferredLocales(),它会自动处理不同系统、不同配置方式下的语言设置解析,兼容各类复杂的用户语言配置场景(如多语言优先级、地区变体等)。

这一功能是实现应用多语言适配的基础——通过获取用户的首选语言,应用可自动切换界面文本、音频、字体等资源,提升本地化体验。


函数

  • SDL_GetPreferredLocales:获取用户的首选区域设置列表,返回 SDL_Locale 结构体数组(数组末尾以 NULL 结尾);函数内部自动分配内存,调用者需通过 SDL_free() 释放整个数组

数据类型

  • (无)

结构体

  • SDL_Locale:区域设置结构体,包含两个核心字段:
    • language:语言代码(符合 ISO 639 标准,如 "zh" 表示中文、"en" 表示英文、"ja" 表示日文)
    • country:国家/地区代码(符合 ISO 3166 标准,如 "CN" 表示中国、"US" 表示美国、"TW" 表示中国台湾);若未指定地区,该字段为 NULL

枚举

  • (无)

  • (无)

FreeBASIC 示例代码

' 引入 SDL 相关声明(需确保 FreeBASIC 已链接 SDL3 库)
#Include "SDL.bi"

' 补充结构体和函数声明(FreeBASIC 绑定可能缺失)
Type SDL_Locale
    language As ZString Ptr   ' 语言代码(如 "zh"、"en")
    country As ZString Ptr    ' 国家/地区代码(如 "CN"、"US",NULL 表示未指定)
End Type

Declare Function SDL_GetPreferredLocales CDecl () As SDL_Locale Ptr
Declare Sub SDL_free CDecl (ByVal ptr As Any Ptr)

' 打印区域设置信息
Sub PrintLocaleInfo(ByVal locale As SDL_Locale Ptr)
    If (locale = NULL) Then
        SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "  - 无区域信息")
        Exit Sub
    End If

    ' 拼接语言+地区字符串(如 "zh-CN"、"en-US")
    Dim As ZString * 32 localeStr
    If (locale->country <> NULL) Then
        snprintf(@localeStr, sizeof(localeStr), "%s-%s", *locale->language, *locale->country)
    Else
        snprintf(@localeStr, sizeof(localeStr), "%s", *locale->language)
    End If

    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "  - %s", localeStr)

    ' 补充语言/地区说明
    If (strcmp(locale->language, "zh") = 0) Then
        SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "    语言:中文")
        If (locale->country <> NULL) Then
            If (strcmp(locale->country, "CN") = 0) Then
                SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "    地区:中国大陆")
            ElseIf (strcmp(locale->country, "TW") = 0) Then
                SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "    地区:中国台湾")
            ElseIf (strcmp(locale->country, "HK") = 0) Then
                SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "    地区:中国香港")
            End If
        End If
    ElseIf (strcmp(locale->language, "en") = 0) Then
        SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "    语言:英文")
        If (locale->country <> NULL And strcmp(locale->country, "US") = 0) Then
            SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "    地区:美国")
        ElseIf (locale->country <> NULL And strcmp(locale->country, "GB") = 0) Then
            SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "    地区:英国")
        End If
    ElseIf (strcmp(locale->language, "ja") = 0) Then
        SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "    语言:日文")
    End If
End Sub

' 获取并解析用户首选区域列表
Sub GetPreferredLocalesExample()
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "【获取用户首选区域设置】")

    ' 1. 获取首选区域列表(SDL 自动分配内存)
    Dim As SDL_Locale Ptr locales = SDL_GetPreferredLocales()
    If (locales = NULL) Then
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "获取区域设置失败:%s", SDL_GetError())
        Exit Sub
    End If

    ' 2. 遍历并打印所有区域设置(数组以 NULL 结尾)
    Dim As Integer i = 0
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "用户首选区域列表(按优先级排序):")
    While (locales[i].language <> NULL)
        SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "第 %d 项:", i + 1)
        PrintLocaleInfo(@locales[i])
        i += 1
    Wend

    If (i = 0) Then
        SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "未获取到任何区域设置")
    End If

    ' 3. 释放 SDL 分配的内存(必须调用,避免内存泄漏)
    SDL_free(locales)
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "区域设置内存已释放")
End Sub

' 根据区域设置选择应用语言
Sub SelectAppLanguage()
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, vbCrLf & "【根据区域设置选择应用语言】")

    Dim As SDL_Locale Ptr locales = SDL_GetPreferredLocales()
    If (locales = NULL) Then
        SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "使用默认语言:英文")
        Exit Sub
    End If

    ' 遍历首选区域列表,匹配支持的语言
    Dim As ZString Ptr appLang = StrPtr("en") ' 默认语言:英文
    Dim As Integer i = 0
    While (locales[i].language <> NULL)
        ' 检查是否支持该语言
        If (strcmp(locales[i].language, "zh") = 0) Then
            appLang = StrPtr("zh")
            ' 进一步区分简繁(根据地区)
            If (locales[i].country <> NULL) Then
                If (strcmp(locales[i].country, "TW") = 0 Or strcmp(locales[i].country, "HK") = 0) Then
                    appLang = StrPtr("zh-TW") ' 繁体中文
                Else
                    appLang = StrPtr("zh-CN") ' 简体中文
                End If
            End If
            Exit While ' 匹配到首选语言,停止遍历
        ElseIf (strcmp(locales[i].language, "ja") = 0) Then
            appLang = StrPtr("ja") ' 日文
            Exit While
        End If
        i += 1
    Wend

    ' 输出选择结果
    Select Case *appLang
        Case "zh-CN": SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "应用语言切换为:简体中文")
        Case "zh-TW": SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "应用语言切换为:繁体中文")
        Case "ja": SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "应用语言切换为:日文")
        Case Else: SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "应用语言切换为:英文(默认)")
    End Select

    ' 释放内存
    SDL_free(locales)
End Sub

' 主程序
Sub Main()
    ' 初始化 SDL(Locale 子系统无需特定子系统,基础初始化即可)
    If (SDL_Init(0) < 0) Then
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL 初始化失败:%s", SDL_GetError())
        Exit Sub
    End If

    ' 运行示例
    GetPreferredLocalesExample()
    SelectAppLanguage()

    ' 清理 SDL
    SDL_Quit()

    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, vbCrLf & "程序正常退出")
End Sub

' 运行主程序
Main()

核心知识点补充

  1. 区域代码规范

    • 语言代码遵循 ISO 639-1(两位小写,如 zh=中文、en=英文、fr=法语);
    • 地区代码遵循 ISO 3166-1 alpha-2(两位大写,如 CN=中国、US=美国、JP=日本);
    • 组合格式为 语言-地区(如 zh-CN=简体中文(中国大陆)、en-US=美式英语、zh-TW=繁体中文(中国台湾))。
  2. 平台实现逻辑 平台 获取语言设置的原生方式 SDL 封装优势
    Windows GetUserPreferredUILanguages 自动处理多语言优先级、兼容旧系统版本
    macOS CFLocaleCopyPreferredLanguages 统一返回格式,无需处理 CoreFoundation 类型
    Linux 读取 LANG/LC_* 环境变量 解析复杂的 locale 字符串(如 zh_CN.UTF-8
    移动平台 Android: getResources().getConfiguration()
    iOS: NSLocale
    跨平台统一返回 SDL_Locale 结构体
  3. 内存管理注意

    • SDL_GetPreferredLocales() 返回的数组由 SDL 分配内存,必须调用 SDL_free() 释放,否则会导致内存泄漏;
    • 数组内的 language/country 字符串是数组内存的一部分,无需单独释放;
    • 数组以 language = NULL 的元素结尾,遍历需以此为终止条件。
  4. 常见区域设置示例 区域字符串 含义 应用适配建议
    zh-CN 简体中文(中国大陆) 使用简体中文字体、简体文本资源
    zh-TW 繁体中文(中国台湾) 使用繁体中文字体、繁体文本资源
    en-US 美式英语 使用美式拼写(如 color/center)
    en-GB 英式英语 使用英式拼写(如 colour/centre)
    ja-JP 日文(日本) 使用日文字体、日文文本资源

总结

  1. 核心优势

    • 跨平台统一的区域设置获取接口,无需适配不同系统的原生语言 API;
    • 自动解析复杂的系统语言配置,返回标准化的「语言+地区」格式;
    • 轻量易用,仅一个核心函数即可完成所有逻辑,降低本地化开发成本。
  2. 使用建议

    • 应用启动时调用 SDL_GetPreferredLocales(),优先匹配用户首选语言;
    • 按优先级遍历区域列表,匹配到支持的语言后立即停止(无需遍历全部);
    • 必须调用 SDL_free() 释放返回的数组,避免内存泄漏;
    • 对未匹配到的语言,默认使用英文(或应用核心语言)保证可用性。
  3. 关键点回顾

    • SDL_GetPreferredLocales() 是区域设置子系统的唯一核心函数,返回按优先级排序的 SDL_Locale 数组;
    • SDL_Locale 包含 language(语言代码)和 country(地区代码)两个字段,地区代码可能为 NULL;
    • 返回的数组必须通过 SDL_free() 释放,这是避免内存泄漏的关键;
    • 区域设置是应用本地化的基础,需结合文本资源、字体、格式适配等功能使用。

评论一下?

OωO
取消