2014-01-09 3 views
1

Я пытаюсь понять, как получить строку из небезопасного указателя байта в следующей структуре. SDL_TEXTINPUTEVENT_TEXTSIZE является 32.Получение строки от небезопасного указателя байта к фиксированному массиву символов

[StructLayout(LayoutKind.Sequential)] 
public unsafe struct SDL_TextInputEvent 
{ 
    public SDL_EventType type; 
    public UInt32 timestamp; 
    public UInt32 windowID; 
    public fixed byte text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; 
} 

Я пробовал:

byte[] rawBytes = new byte[SDL_TEXTINPUTEVENT_TEXT_SIZE]; 

unsafe 
{ 
    Marshal.Copy((IntPtr)rawEvent.text.text, rawBytes, 0, SDL_TEXTINPUTEVENT_TEXT_SIZE); 
} 

string text = System.Text.Encoding.UTF8.GetString(rawBytes); 

Какой вид работ, но дает мне строку с большим количеством дополнительных байтов за пределами символа, который фактически вошли. Должен ли я разбирать массив байтов и искать 0-завершающий символ, чтобы избежать избытка?

Я что-то совершенно недопонимаю?

Для справки, исходный C структура, которая в настоящее время выстраивали в .NET является время выполнения:

typedef struct SDL_TextInputEvent 
{ 
    Uint32 type; 
    Uint32 timestamp; 
    Uint32 windowID; 
    char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; 
} SDL_TextInputEvent; 
+0

Вам нужно фактически использовать 'byte' в .NET struct? Вы должны уметь хранить подпись массива 'char', я бы подумал, а затем, когда это необходимо, превратить это в обрезанную строку. – TyCobb

+0

@ Этот символ имеет 16 бит в C#, но бит B в неуправляемом коде –

ответ

2

Вам нужно найти нуль-терминатор. И Marshal.Copy этого не сделает. Вы можете использовать Marshal.PtrToStringAnsi, если ваш текст был закодирован ANSI. Но для UTF-8 такой функции нет. Поэтому вам нужно перебрать массив, ищущий нулевой байт. Когда вы сталкиваетесь с этим, вы знаете фактическую длину буфера, и вы можете изменить существующий код, чтобы использовать эту длину, а не максимально возможную длину.

+0

Я подозревал, что так много, спасибо за подтверждение. –