2014-12-22 2 views
0

Я создаю клиента Spotify с использованием C# и LibspotifyDotNet для целей доступности.Плейлист имеет только первую букву с именем

Я реализую метод, который создаст новый список воспроизведения в контейнере сеанса пользователя по умолчанию с заданным именем. Он работает, вроде. За исключением того, что в плейлисте всегда указано его имя на первую введенную букву, а не всю строку.

Вот код, я использую

public IntPtr CreateNewPlaylist(string name) 
{ 
    IntPtr namePointer = IntPtr.Zero; 
    try 
    { 
     var sessionContainerPointer = libspotify.sp_session_playlistcontainer(GetSession()); 
     namePointer = Marshal.StringToHGlobalUni(name); 
     var newPointer = libspotify.sp_playlistcontainer_add_new_playlist(sessionContainerPointer, namePointer); 
     return newPointer; 
    } 
    finally 
    { 
     if (namePointer != IntPtr.Zero) 
      Marshal.FreeHGlobal(namePointer); 
    } 
} 

Я проверить, что namePointer действительно указывают на всю строку, превратив его обратно в строку, чтобы увидеть, что она возвращает. У нас все хорошо.

Я пропустил что-то очевидное здесь? Или это проблема LibspotifyDotNet? Или Libspotify один?

Спасибо.

ответ

0

C# хранит строки в виде двух байтов на строку в памяти, поэтому для нормальных значений 0-127 ascii, например, как «ABC», у нее будет шаблон 0x41,0x00,0x42,0x00,0x43,0x00 в памяти.

documentation для libspotify показывает, что sp_playlistcontainer_add_new_playlist принимает второй аргумент const char*.

Таким образом, spotify lib видит первый байт двух байтового символа в качестве первой буквы строки, которую вы отправляете, а затем видит второй байт символа unicode, который равен 0x00. Поскольку он считает, что он имеет дело с одной байтовой строкой, а C заканчивает строки с 0x00, он обрабатывает это как конец строки.

Попробуйте кодировать строку в одиночную строку символов в массиве байтов, используя ASCIIEncoding.GetBytes, прежде чем передавать ее на api.

+0

Спасибо за ваш ответ. Так вы говорите, что используете Encoding.X.GetBytes, чтобы получить массив байтов и скопировать его в память и использовать этот указатель? Я бы подумал, что это будет так, как работает StringToHGlobalUni, но я думаю, что нет. –

+0

Да, используйте ASCIIEncoding или UTF8Encoding. StringToHGlobalUni просто выделяет неуправляемый буфер и копирует в него данные строки. –

+1

Отлично! Он работает так, как ожидалось. Спасибо. –

Смежные вопросы