Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
编组一个C++;将字符串编码为C# 我试图用C++程序编写的一个文件中读取(我没有源代码)。我一直在尝试将此结构读入C#,并将其整理到目前为止,但没有成功_C#_.net - Fatal编程技术网

编组一个C++;将字符串编码为C# 我试图用C++程序编写的一个文件中读取(我没有源代码)。我一直在尝试将此结构读入C#,并将其整理到目前为止,但没有成功

编组一个C++;将字符串编码为C# 我试图用C++程序编写的一个文件中读取(我没有源代码)。我一直在尝试将此结构读入C#,并将其整理到目前为止,但没有成功,c#,.net,C#,.net,结构基本上是一组固定长度的字符串,每个字符两个字节。在C++中,它们可以被声明为TCHAR(8)。 磁盘上的数据如下所示: 我尝试了以下C#代码,我知道它可以成功地将值作为字符串读入: public void ReadTwoStringsOfFixedLength() { string field1 = string.Empty; string field2 = string.Empty; FileReadString(handle, out field1, 1

结构基本上是一组固定长度的字符串,每个字符两个字节。在C++中,它们可以被声明为TCHAR(8)。 磁盘上的数据如下所示:

我尝试了以下C#代码,我知道它可以成功地将值作为字符串读入:

public void ReadTwoStringsOfFixedLength()
{ 
     string field1 = string.Empty;
     string field2 = string.Empty;
     FileReadString(handle, out field1, 16);
     FileReadString(handle, out field2, 16);
}

public static void FileReadString(BinaryReader reader, out string outVal, int length)
{
    var mem = new MemoryStream();
    outVal = string.Empty;

    byte b = 0;
    for (int i = 0; i < length; i++)
    {
        b = reader.ReadByte();
        if (b != 0) mem.WriteByte(b);
    }
    outVal = Encoding.GetEncoding(1252).GetString(mem.ToArray());
}
请注意,我还尝试使用
CharSet.Unicode
,但是结果字符串是乱码


如果您能帮助修复代码,我们将不胜感激。

我认为您需要在
StructLayout
上设置
CharSet=CharSet.Unicode

ASCII/ANSI中的
46 00 69 00
被视为单个字符和空终止符。显示双字节字符需要
CharSet.Unicode
,例如您正在显示的字符


SizeConst
值也必须是字符数,而不是字节数。

是否零字节被视为终止符而不是UTF-16编码的一部分?MFC中的一些字符串表使用\0\0作为2字节字符的字符串终止符/字段分隔符。这并不是你问题的答案,只是如果你有任何可变长度的字符串可能会有所帮助。嗨@DrewNoakes,情况似乎确实如此,我只是不确定我需要使用什么编组方法来解决这个问题(如果可能的话)。也许唯一的解决方法是将封送处理为字节数组并进行转换?您是否考虑过不使用marsheling字符串?您可以固定内存,然后将指针传递到C#,然后在数组上构造Span/memory[char]。不完全是字符串。但是它会很快变得愚蠢。嗨,阿隆,你有没有一个例子来说明你的意思?如果可能的话,我最好在不转换字节字符串的情况下一次性读取结构。嗨,Drew,我想你是对的!尽管您能补充一个事实,即我还需要将“SizeConst”的大小减半为8(即字符数而不是字节数)。这就是造成额外数据混乱的原因。我会记下你的答案,谢谢!这相当令人困惑,CharSet.Unicode映射到UTF16?@aron有许多Unicode变体。文档称
Unicode
表示2字节字符,又名UTF-16,又名“16位Unicode转换格式”:@Aron Microsoft文档有一个很长的“传统”,即调用Unicode来实现他们真正应该调用的UTF-16。“Unicode”的真正含义远不止于此,微软在其文档中总是混淆这两者。我想这是作为早期采用者的一份遗产。请记住,Unicode最初只需要2^16个字符,所以UTF-16是最适合的。。。直到后来才引入了其他平面(和代理对)。这个名字反映了这段历史,无论是好是坏。
void Main()
{
   byte[] abBuffer = handle.ReadBytes(Marshal.SizeOf(typeof(MyStruct)));
   //Access data
   GCHandle pinnedPacket = GCHandle.Alloc(abBuffer, GCHandleType.Pinned);
   var atTestStruct = (MyStruct)Marshal.PtrToStructure(pinnedPacket.AddrOfPinnedObject(), typeof(MyStruct));
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi), Serializable]
struct MyStruct
{
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
   string Field1   // Resulting value = "F"; 
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
   string Field2;  // Resulting value = "F" 
 }