C# CharSet.Ansi使用哪种编码?
C# CharSet.Ansi使用哪种编码?,c#,.net-core,C#,.net Core,CharSet.Ansi使用哪个System.Text.Encoding 我想在.NET核心应用程序中解码一个字符串(在C++代码之前被封送),而不定义结构,使用 MARHALAL.PTRtoStult < /P> Encoding.GetEncoding(???).GetString(...) 在.NET Framework应用程序中System.Text.Encoding.Default起作用: [StructLayout(LayoutKind.Sequential, Pack = 1,
CharSet.Ansi
使用哪个System.Text.Encoding
我想在.NET核心应用程序中解码一个字符串(在C++代码之前被封送),而不定义结构,使用<代码> MARHALAL.PTRtoStult < /P>
Encoding.GetEncoding(???).GetString(...)
在.NET Framework应用程序中System.Text.Encoding.Default
起作用:
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public struct Structure
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]
public string FieldA;
}
public class Net461App
{
static void Main(string[] args)
{
var @struct = new Structure { FieldA = "äöüß" };
byte[] buffer = ToByteArray(@struct);
var unmarshalled = ToStructure<Structure>(buffer).FieldA; // "äöüß"
Console.WriteLine(Encoding.Default.GetString(buffer).Trim('\0')); // "äöüß"
Console.WriteLine(Encoding.Default.EncodingName); // Western European (Windows)
Console.WriteLine(Encoding.Default.CodePage); // 1252
int ansiCodePage = Thread.CurrentThread.CurrentCulture.TextInfo.ANSICodePage; // 1252
Encoding ansiEncoding = Encoding.GetEncoding(ansiCodePage); // works
Console.WriteLine(ansiEncoding.GetString(buffer).Trim('\0')); // "äöüß"
Console.WriteLine(ansiEncoding.EncodingName); // Western European (Windows)
Console.WriteLine(ansiEncoding.CodePage); // 1252
}
public static byte[] ToByteArray<T>(T structure) where T : struct
{
var buffer = new byte[Marshal.SizeOf(structure)];
IntPtr handle = Marshal.AllocHGlobal(buffer.Length);
try
{
Marshal.StructureToPtr(structure, handle, true);
Marshal.Copy(handle, buffer, 0, buffer.Length);
return buffer;
}
finally
{
Marshal.FreeHGlobal(handle);
}
}
public static T ToStructure<T>(byte[] buffer) where T : struct
{
IntPtr handle = Marshal.AllocHGlobal(buffer.Length);
try
{
Marshal.Copy(buffer, 0, handle, buffer.Length);
return Marshal.PtrToStructure<T>(handle);
}
finally
{
Marshal.FreeHGlobal(handle);
}
}
}
更新:
在调查使用建议时,我发现了以下关于获取系统当前ANSI代码页的提示:
Encoding.GetEncoding
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
int currentAnsiCodePage = Encoding.GetEncoding(0).CodePage;
Encoding encoding = Encoding.GetEncoding(currentAnsiCodePage);
以下每一项都为我提供了正确解码测试中字符串的相同代码页
- Encoding.GetEncoding(0).CodePage(需要
注册)CodePagesEncodingProvider
- Thread.CurrentThread.CurrentCulture.TextInfo.ANSICodePage
- CultureInfo.CurrentCulture.TextInfo.ANSICodePage
不确定哪一个更可取,并且适用于所有机器。我希望Ansi始终返回系统区域设置代码页,即1252用于西欧Windows,1250用于捷克语,1251用于俄语,等等。至于1252未知,请参见此处:但如何以编程方式获取当前系统本地代码页?TextInfo.ANSICodePage是正确的方法吗?我希望是这样的,是的。本机函数中称为“ANSI”的东西(我应该指出,它不是ANSI,而是用词不当的非常旧的)是由检索到的当前系统代码页。如果编写我知道特定于Windows的P/Invoke代码,我可能更喜欢调用它,而不是试图找出哪段托管代码与之完全对应。如果代码必须是可移植的,我想所有的赌注都没有了
CultureInfo.CurrentCulture.TextInfo.ANSICodePage应该可以,但我不知道它是如何在Linux上实现的。
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
int currentAnsiCodePage = Encoding.GetEncoding(0).CodePage;
Encoding encoding = Encoding.GetEncoding(currentAnsiCodePage);