SDL3_API分类参考_GUID 处理(CategoryGUID)

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

GUID 处理子系统(CategoryGUID)

GUID(全局唯一标识符)是一个 128 位的数值,用于唯一标识某个对象/实体——其核心特性是「全局唯一性」,可确保在不同系统、不同场景下不会出现重复值。

SDL 为 GUID 提供了核心的序列化/反序列化能力:支持将二进制格式的 GUID 转换为人类可读的字符串格式,也支持将字符串格式的 GUID 解析回二进制结构,方便存储、传输和展示。


函数

  • SDL_GUIDToString:将二进制格式的 SDL_GUID 结构体转换为字符串格式(输出如 "12345678-1234-1234-1234-1234567890ab"),参数需指定输出缓冲区大小以避免溢出
  • SDL_StringToGUID:将字符串格式的 GUID(标准 UUID 格式)解析为二进制的 SDL_GUID 结构体,解析失败时返回全零的 GUID

数据类型

  • (无)

结构体

  • SDL_GUID:存储 128 位 GUID 的二进制结构体,内部包含一个 16 字节的数组(对应 128 位),是 SDL 中表示 GUID 的核心数据结构

枚举

  • (无)

  • (无)

FreeBASIC 示例代码

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

' 补充 SDL_GUID 结构体和函数声明(FreeBASIC 绑定可能缺失)
Type SDL_GUID
    data(0 To 15) As Uint8  ' 16字节 = 128位,存储GUID的二进制数据
End Type

' GUID字符串的标准长度:36个可见字符 + 1个终止符 = 37
Const SDL_GUID_STRING_LENGTH = 37

Declare Sub SDL_GUIDToString CDecl ( _
    ByVal guid As SDL_GUID, _
    ByVal str As ZString Ptr, _
    ByVal maxlen As Size_t _
)

Declare Function SDL_StringToGUID CDecl ( _
    ByVal str As ZString Ptr _
) As SDL_GUID

' 辅助函数:打印二进制 GUID 数据
Sub PrintGUIDBinary(ByVal guid As SDL_GUID)
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "GUID 二进制数据(16字节):")
    For i As Integer = 0 To 15
        SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "  字节 %2d: 0x%02X", i, guid.data(i))
        ' 每4字节换行,方便阅读
        If ((i + 1) Mod 4 = 0) Then
            SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "")
        End If
    Next
End Sub

' 辅助函数:比较两个 GUID 是否相等
Function GUIDEquals(ByVal a As SDL_GUID, ByVal b As SDL_GUID) As SDL_bool
    For i As Integer = 0 To 15
        If (a.data(i) <> b.data(i)) Then
            Return SDL_FALSE
        End If
    Next
    Return SDL_TRUE
End Function

' ==================== 示例 1:GUID 转字符串 ====================
Sub GUIDToStringExample()
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "【示例 1:GUID 转字符串】")

    ' 构造一个测试用的 GUID(二进制数据)
    Dim As SDL_GUID testGUID
    ' 手动填充测试数据(模拟一个真实的 GUID 二进制值)
    testGUID.data(0)  = &H12 : testGUID.data(1)  = &H34 : testGUID.data(2)  = &H56 : testGUID.data(3)  = &H78
    testGUID.data(4)  = &H90 : testGUID.data(5)  = &HAB : testGUID.data(6)  = &HCD : testGUID.data(7)  = &HEF
    testGUID.data(8)  = &H11 : testGUID.data(9)  = &H22 : testGUID.data(10) = &H33 : testGUID.data(11) = &H44
    testGUID.data(12) = &H55 : testGUID.data(13) = &H66 : testGUID.data(14) = &H77 : testGUID.data(15) = &H88

    ' 打印二进制 GUID
    PrintGUIDBinary(testGUID)

    ' 转换为字符串格式
    Dim As ZString * SDL_GUID_STRING_LENGTH guidStr
    SDL_GUIDToString(testGUID, @guidStr, sizeof(guidStr))

    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "GUID 转换为字符串:%s", guidStr)
End Sub

' ==================== 示例 2:字符串转 GUID ====================
Sub StringToGUIDExample()
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, vbCrLf & "【示例 2:字符串转 GUID】")

    ' 标准格式的 GUID 字符串(UUID 格式)
    Dim As ZString Ptr guidStr = StrPtr("12345678-90ab-cdef-1122-334455667788")
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "待解析的 GUID 字符串:%s", guidStr)

    ' 将字符串解析为二进制 GUID
    Dim As SDL_GUID parsedGUID = SDL_StringToGUID(guidStr)

    ' 打印解析后的二进制数据
    PrintGUIDBinary(parsedGUID)

    ' 验证解析结果:转换回字符串,检查是否与原字符串一致
    Dim As ZString * SDL_GUID_STRING_LENGTH checkStr
    SDL_GUIDToString(parsedGUID, @checkStr, sizeof(checkStr))
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "解析后转回字符串:%s", checkStr)

    If (SDL_strcmp(guidStr, @checkStr) = 0) Then
        SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "✓ 解析与转换结果一致")
    Else
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "✗ 解析与转换结果不一致")
    End If
End Sub

' ==================== 示例 3:无效 GUID 字符串处理 ====================
Sub InvalidGUIDStringExample()
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, vbCrLf & "【示例 3:无效 GUID 字符串处理】")

    ' 无效的 GUID 字符串(长度不足、格式错误)
    Dim As ZString Ptr invalidStrs(2) = { _
        StrPtr("12345678-90ab-cdef-1122"),  ' 长度不足
        StrPtr("12345678-90ab-cdef-1122-zzzzzzzzzzzz"),  ' 包含非十六进制字符
        StrPtr("无效的GUID字符串")  ' 完全错误格式
    }

    ' 全零 GUID(用于对比解析失败的情况)
    Dim As SDL_GUID zeroGUID
    For i As Integer = 0 To 15
        zeroGUID.data(i) = 0
    Next

    For i As Integer = 0 To 2
        SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "解析无效字符串:%s", invalidStrs(i))
        Dim As SDL_GUID parsedGUID = SDL_StringToGUID(invalidStrs(i))

        If (GUIDEquals(parsedGUID, zeroGUID) = SDL_TRUE) Then
            SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "  → 解析失败,返回全零 GUID")
        Else
            SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "  → 解析结果非全零(意外情况)")
        End If
    Next
End Sub

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

    ' 运行示例
    GUIDToStringExample()
    StringToGUIDExample()
    InvalidGUIDStringExample()

    ' 清理 SDL
    SDL_Quit()

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

' 运行主程序
Main()

核心知识点补充

  1. GUID 格式规范

    • SDL 遵循标准 UUID v4 格式:8-4-4-4-12 共 36 个字符(含 4 个连字符),例如 12345678-1234-1234-1234-1234567890ab
    • 二进制存储为 16 字节(128 位),字符串格式是其十六进制的可读性表示;
    • SDL_GUIDToString 的输出缓冲区至少需要 37 字节(36 个字符 + 1 个字符串终止符 \0)。
  2. 解析/转换规则

    • SDL_StringToGUID 仅支持标准 UUID 格式的字符串,非标准格式(如无连字符、大小写混合、非十六进制字符)会解析失败;
    • 解析失败时返回全零的 SDL_GUID(所有 16 字节均为 0),可通过对比全零 GUID 判断解析是否成功;
    • SDL_GUIDToString 输出的字符串为小写形式,输入字符串为大写时也可正常解析(大小写不敏感)。
  3. 典型使用场景

    • 标识游戏控制器/输入设备(SDL 中常用于区分不同的物理设备);
    • 生成唯一的用户/设备 ID 用于数据存储/传输;
    • 跨平台唯一标识资源(如配置文件、缓存数据)。
  4. 跨平台注意事项

    • SDL_GUID 结构体的二进制布局在所有平台一致,可安全序列化/反序列化;
    • 字符串格式的 GUID 无平台差异,是跨平台传输的首选格式;
    • 避免手动修改 SDL_GUID 的二进制数据,如需生成新 GUID,需使用平台原生的 GUID 生成函数(如 Windows 的 CoCreateGuid)。

总结

  1. 核心优势

    • 提供简单统一的 GUID 序列化/反序列化接口,无需手动处理二进制与字符串的转换;
    • 严格遵循标准 UUID 格式,保证与其他系统/库的兼容性;
    • 解析失败时返回可预测的全零 GUID,便于错误处理。
  2. 使用建议

    • 转换字符串时,务必使用 SDL_GUID_STRING_LENGTH(37)作为缓冲区大小,避免溢出;
    • 解析字符串后,先对比全零 GUID 判断是否解析成功,再进行后续操作;
    • 存储 GUID 时优先选择字符串格式(易读、易调试),传输/存储体积敏感时使用二进制格式。
  3. 关键点回顾

    • SDL_GUID 是 16 字节的结构体,用于存储 128 位的全局唯一标识符;
    • SDL_GUIDToString/SDL_StringToGUID 实现 GUID 二进制与字符串的双向转换;
    • 解析无效字符串时返回全零 GUID,可通过对比全零值判断解析结果;
    • 字符串格式遵循标准 UUID 格式(36 字符 + 终止符),缓冲区需至少 37 字节。

评论一下?

OωO
取消