You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用LibraryImport正确包装SDL的SDL_GetDisplays函数?

最优SDL_GetDisplays C#包装方案:兼顾安全与易用性

针对SDL的SDL_GetDisplays函数,两种现有方案各有优劣,要同时满足安全性和易用性,最合理的做法是提供底层严格匹配+上层易用封装的重载组合,具体分析和实现如下:

现有方案的优缺点

方案1(IntPtr传递count)

  • 优势:完全匹配原C函数的int* count参数,支持传递IntPtr.Zero对应原函数的NULL,严格遵循函数契约,无未定义行为风险。
  • 劣势:用户使用时需要手动处理指针(比如用Marshal.ReadInt32读取count值),操作繁琐,不够直观。

方案2(out int count)

  • 优势:调用极其便捷,用户无需关心指针细节,直接拿到count值。
  • 劣势:无法传递NULL参数,违背原函数的设计意图;如果用户不需要count值,只能被迫接收一个无用变量,存在潜在的未定义行为风险(尽管SDL可能兼容,但严格来说不符合C函数的参数约定)。

推荐的实现方式

通过私有底层方法+公共重载的组合,既保留原函数的全部能力,又给用户提供友好的调用接口:

1. 底层严格匹配的原生方法

先实现一个私有/内部方法,完全对应原C函数的签名,确保兼容性:

[LibraryImport(SDLLibrary, EntryPoint = "SDL_GetDisplays"), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
private static partial IntPtr GetDisplaysNative(IntPtr count);

2. 上层易用的公共重载

提供两个公共方法,分别对应不同的使用场景:

场景1:需要获取显示器数量(count)

直接用out int count封装,内部自动处理指针的分配和读取:

public static IntPtr GetDisplays(out int count)
{
    var countPtr = Marshal.AllocHGlobal(sizeof(int));
    try
    {
        var result = GetDisplaysNative(countPtr);
        count = Marshal.ReadInt32(countPtr);
        return result;
    }
    finally
    {
        Marshal.FreeHGlobal(countPtr);
    }
}

场景2:不需要获取显示器数量

直接传递IntPtr.Zero,对应原函数的NULL参数:

public static IntPtr GetDisplays()
{
    return GetDisplaysNative(IntPtr.Zero);
}

额外优化(可选)

如果想进一步简化用户操作,可以封装返回的SDL_DisplayID数组,并自动释放SDL分配的内存:

// 假设已定义SDL_DisplayID结构体和SDL_Free的包装方法
public static SDL_DisplayID[] GetDisplaysSafe(out int count)
{
    count = 0;
    var arrayPtr = GetDisplays(out count);
    if (arrayPtr == IntPtr.Zero)
    {
        return Array.Empty<SDL_DisplayID>();
    }

    var displayIds = new SDL_DisplayID[count];
    var elementSize = Marshal.SizeOf<SDL_DisplayID>();
    for (int i = 0; i < count; i++)
    {
        var elementPtr = IntPtr.Add(arrayPtr, i * elementSize);
        displayIds[i] = Marshal.PtrToStructure<SDL_DisplayID>(elementPtr);
    }

    // 释放SDL分配的内存
    SDL_Free(arrayPtr);
    return displayIds;
}

内容的提问来源于stack exchange,提问作者Eduard Gushchin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 22:29:59