将 ByValTStr 编组为 UTF8

Marshalling ByValTStr as UTF8

我正在使用 C DLL,但在使用 P/Invoke 编组字符串时遇到问题。

DLL 的结构如下:

typedef struct
{
    char sAddress[256];
    BYTE byUseRtsp;
    WORD wPort;
}INFO,*LPINFO;

我的 C# 结构如下所示:

[StructLayout(LayoutKind.Sequential)]
public struct INFO
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string sAddress;

    public byte byUseRtsp;

    public short wPort;
}

sAddress 的字符串编组适用于 ASCII 文本,但 DLL 自始至终使用 UTF-8 编码。因此,一旦使用多字节字符,编组就会使文本出现乱码。使用 CharSet.Unicode 在这里不起作用,因为它告诉编组器将 encode/decode 字符串作为 Windows 上的 UTF-16。我需要一个 CharSet.Utf8,不幸的是它不存在。

有一个解决方法,但它很丑陋,希望尽可能避免。解决方法是替换:

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string sAddress;

与:

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
    public byte[] sAddress;

然后重新编写我的代码以使用 Encoding.UTF8.GetBytes/String() 方法获取字符串值。我还需要用这种方法自己处理空终止符。

有更好的方法吗?

Is there a better way of doing this?

使用内置选项来整理您所做的事情可能已经很好了。您可能想编写一些辅助方法来为您管理它,但我相信您对此很感兴趣。

除此之外,您还可以使用自定义封送拆收器。我不知道有大量关于此主题的工作。比较完整的一个恰好是我的这个问题:How do I write a custom marshaler which allows data to flow from native to managed?