我试图在C#中封送一个hid_device_info结构,但我不知道如何将wchar_t*字符串转换为托管C#字符串。我尝试了MarshalAs属性中所有可能的值,但所有这些值都只返回第一个字符,没有返回其他字符。
我已经尝试用指针替换所有的宽字符串,这样我就可以手动查看它们,这就是我到目前为止所使用的结构:
public struct HidDeviceInfo
{
public IntPtr path; // This one marshals fine because it's just a regular char_t*
public ushort vendor_id;
public ushort product_id;
public IntPtr serial_number; // wchar_t*
public ushort release_number;
public IntPtr manufacturer_string; // wchar_t*
public IntPtr product_string; // wchar_t*
public ushort usage_page;
public ushort usage;
public int interface_number;
public IntPtr next;
}当我手动迭代其中一个指针(例如serial_number)时,我可以看到所有字符都有4个字节(1个ascii字节后面跟着3个0)。我尝试了所有可能的Marshal.PtrToString...方法,但没有一个方法能够检索完整的字符串。
我怀疑字符串被视为2字节字符,因为我不能在C#中指定字符宽度,这就是它在第一个字符后停止的原因。当然,通过了解这一点,我可以很容易地编写自己的字符串编组拆收器,但我觉得必须有一个现有的解决方案,而我忽略了一些显而易见的东西。
此结构来自P/Invoked函数和Marshal.PtrToStructure
[DllImport(LibUsbName, CharSet = CharSet.Unicode)]
public static extern IntPtr hid_enumerate(ushort vendorId, ushort productId);我还尝试了所有可能的CharSet值。
这不可能是字符类型不匹配,就像在this question中一样,因为我已经尝试了不同字符类型的所有可能组合。
发布于 2020-10-04 02:38:27
我最终写了这个方法,它对我来说很好,但前提是所有字符都是ASCII,并且字符宽度保证为4个字节。
private static string ToUcs4String(this IntPtr ptr)
{
var builder = new StringBuilder();
var buffer = new byte[4];
while (true)
{
Marshal.Copy(ptr, buffer, 0, 4);
if (buffer[0] == 0)
break;
builder.Append((char) buffer[0]);
ptr += 4;
}
return builder.ToString();
}https://stackoverflow.com/questions/64187076
复制相似问题