从不安全的字节指针获取字符串到固定的字符数组

Jus*_*les 4 .net c# string pinvoke unsafe

我试图了解如何从以下结构中的不安全字节指针获取字符串。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];
}
Run Code Online (Sandbox Code Playgroud)

我试过了:

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);
Run Code Online (Sandbox Code Playgroud)

哪种有效,但给了我一个字符串,除了实际输入的字符之外,还有很多额外的字节。我应该解析字节数组并搜索以 0 结尾的字符以避免多余的字符吗?

我完全误解了什么吗?

作为参考,被编组到 .NET 运行时的原始 C 结构是:

typedef struct SDL_TextInputEvent
{
    Uint32 type;
    Uint32 timestamp;
    Uint32 windowID;
    char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
} SDL_TextInputEvent;
Run Code Online (Sandbox Code Playgroud)

Dav*_*nan 5

您确实需要找到空终止符。并且Marshal.Copy不会那样做。Marshal.PtrToStringAnsi如果您的文本是 ANSI 编码的,则可以使用。但是UTF-8没有这样的功能。因此,您需要遍历数组以查找零字节。当您遇到这种情况时,您知道缓冲区的实际长度,并且可以修改现有代码以使用该长度而不是最大可能长度。

  • 如果有什么安慰的话,`Marshal.PtrToStringUTF8` 存在于 .NET Core 中,我只是将它用于与 OP 完全相同的目的,同时将 Lazy Foo 教程从 C++ 转换为 C#。 (2认同)