【问题标题】:How do you convert multistring to/from C# string collection?如何将多字符串转换为 C# 字符串集合/从 C# 字符串集合转换?
【发布时间】:2008-11-06 14:39:26
【问题描述】:

多字符串(以空字符分隔的双空字符结尾的字符串)在 Windows API 中很常见。将 API 返回的多字符串转换为 C# 字符串集合(反之亦然)的好方法是什么?

我对正确处理字符编码(Windows XP 及更高版本)特别感兴趣。

下面的方法创建多串似乎没问题,但我没有解码多串的例子。

static string StringArrayToMultiString(
    ICollection<string> stringArray
    )
{
    StringBuilder multiString = new StringBuilder();


    if (stringArray != null)
    {
        foreach (string s in stringArray)
        {
            multiString.Append(s);
            multiString.Append('\0');
        }
    }

    return multiString.ToString();
}

【问题讨论】:

    标签: c# winapi string


    【解决方案1】:

    这可能很幼稚,但是怎么样:

    static string[] MultiStringToArray(string multiString)
    {
        return multiString.TrimEnd('\0').Split('\0');
    }
    

    另外 - 你是不是错过了StringArrayToMultiString 中的最后一个\0 (你声明双空终止)? 如果数组是params string[] 数组,它可能更容易调用 - 类似于:

        static string StringArrayToMultiString(params string[] values)
    {
        if (values == null) throw new ArgumentNullException("values");
        StringBuilder multiString = new StringBuilder();
    
        foreach (string s in values)
        {
            multiString.Append(s);
            multiString.Append('\0');
        }
        return multiString.ToString();
    }
    

    [在澄清最终\0后编辑]

    【讨论】:

    • 我认为当它通过 COM 发送时,字符串中已经存在一个 \0,这意味着他需要一个 \0 而不是另一个。
    • 是的,没错——当一个字符串被传递给 Win32 API 时,它是空终止的。所以没有必要添加最后一个\0。多字符串不能包含空字符串。这意味着常规的空字符串 "" 是没有条目的合法多字符串。
    • 如果 multiString 值包含完整的多字符串值,MultiStringToArray() 方法可以很好地工作,但问题是如何从 API 调用中取回该值。
    • 这里的 TrimEnd 可以用multiString.Split('\0', StringSplitOptions.RemoveEmptyEntries) 省略,因为空字符串不能存储在双空终止列表中。
    【解决方案2】:

    我已经测试了 StringArrayToMultiString 方法,使用 ChangeServiceConfig() 函数来更改 Windows 服务的依赖关系,它适用于零、一个和多个字符串。

    与此同时,我制定了一个解决方案,用于解码从 API 调用接收到的多字符串。例如,SCardListReaders() 函数返回 PC/SC 阅读器名称的多字符串。我将其声明为:

    [DllImport("winscard.dll", CharSet = CharSet.Auto)]
    static extern int SCardListReaders(
        IntPtr context,
        string groups,
        char[] readers,
        ref uint readersLen
        );
    

    请注意,返回多字符串的 reader 参数被声明为 char[]。返回值很容易解析并转换为字符串集合:

    static string[] MultiStringToArray(
        char[] multistring
        )
    {
        List<string> stringList = new List<string>();
        int i = 0;
        while (i < multistring.Length)
        {
            int j = i;
            if (multistring[j++] == '\0') break;
            while (j < multistring.Length)
            {
                if (multistring[j++] == '\0')
                {
                    stringList.Add(new string(multistring, i, j - i - 1));
                    i = j;
                    break;
                }
            }
        }
    
        return stringList.ToArray();
    }
    

    【讨论】:

      【解决方案3】:

      在 RegistryKey.SetValue() 和 RegistryKey.GetValue() 的 MSDN 文档中,示例只是分别传入或转换为 string[]。有什么问题吗?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多