【发布时间】:2016-06-15 09:31:44
【问题描述】:
我在 CharUnion 结构中遇到了 Cyrillic unicode 字符的问题。
这里是 DLLImport 声明:
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool WriteConsoleOutput(
SafeFileHandle hConsoleOutput,
CharInfo[] lpBuffer,
Coord dwBufferSize,
Coord dwBufferCoord,
ref SmallRect lpWriteRegion);
[DllImport("Kernel32.dll", SetLastError = true, CharSet=CharSet.Auto)]
static extern SafeFileHandle CreateFile(
string fileName,
[MarshalAs(UnmanagedType.U4)] uint fileAccess,
[MarshalAs(UnmanagedType.U4)] uint fileShare,
IntPtr securityAttributes,
[MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
[MarshalAs(UnmanagedType.U4)] int flags,
IntPtr template);
使用 WriteConsoleOutputW 或更改 CharSet 只会导致 Ascii 字符显示错误,但使用西里尔 unicode 时没有更改。
以下是结构:
[StructLayout(LayoutKind.Explicit)]
public struct CharUnion
{
[FieldOffset(0)] public char UnicodeChar;
[FieldOffset(0)] public byte AsciiChar;
}
[StructLayout(LayoutKind.Explicit)]
public struct CharInfo
{
[FieldOffset(0)] public CharUnion Char;
[FieldOffset(2)] public short Attributes;
}
创建WriteConsoleOutput 使用的句柄:
SafeFileHandle Handle = CreateFile("CONOUT$", 0x40000000, 2, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);
这是我如何填写它的示例:
CharInfo[] buffer = new CharInfo[10];
buffer.Char.UnicodeChar = '\u0430';
之后,我使用导入的 WriteConsoleOutput 函数将其写入控制台缓冲区。 当我不使用西里尔字母时,它可以正常工作。
如果上面我在输出中得到“0”符号(如果我没记错的话,它等于“\u0030”),在我看来它只是读取了一个字符的字节。
您能帮我解决这个问题吗? 实在找不到相关的东西。
更新:
Console.WriteLine('\u0430');
正确书写字符。所以我认为问题不在于控制台编码。也改变它没有任何结果。
【问题讨论】:
-
您可能没有正确声明您的 dllimport。见C# Getting window's title by handle in Hebrew return question marks
-
@raymond-chen 谢谢你的链接,不幸的是我只能明天才能尝试,一旦我有任何结果,我会通知你再次谢谢你
-
@raymond-chen 正如我所承诺的:更改 CharSet 不会给我任何积极的结果。我也尝试过使用 WriteConsoleOutputW,但还是一样。控制台输出的 Ascii 部分更改为错误符号,但使用 '\u0430' 我仍然在输出中得到“0”。这里没有变化
-
请分享您的 dllimport 声明。
-
@raymond-chen 更新了带有 dllimport 声明并创建 SafeFileHandle 的帖子