将 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?
我正在使用 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?