Как конвертировать мультистроки в / из коллекции строк C #? - PullRequest
5 голосов
/ 06 ноября 2008

Многорядные строки (двойная строка с нулевым символом в конце, разделенная нулем) распространены в 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();
}

Ответы [ 3 ]

8 голосов
/ 06 ноября 2008

Это может быть наивно, но как насчет:

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

Кроме того - разве вы не пропустили окончательный \0 (вы указали окончание с двойным нулем) в StringArrayToMultiString? И было бы проще вызвать, если массив был массивом 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]

2 голосов
/ 06 ноября 2008

Я протестировал метод 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();
}
1 голос
/ 22 сентября 2009

В документации MSDN для RegistryKey.SetValue () и RegistryKey.GetValue () примеры просто передаются или приводятся к строке [] соответственно. Что-то не так с этим?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...