GDAL GDALRATSetValueAsString()如何保存汉字(c#)?

Dra*_*ius 10 c# string unicode gdal

我需要GDAL的帮助.带有中文符号的字符串值未被正确读取/保存(C#).

对于SAVING网格值,我们使用:
private static extern void GDALRATSetValueAsString(IntPtr handle,int row,int field,[In] [MarshalAs(UnmanagedType.LPStr)] string value); 方法(c#)保存字符串值,似乎这个方法将字符串保存为ANSI字符串.

阅读:

private static extern IntPtr GDALRATGetValueAsString(IntPtr handle, int row, int field);
Run Code Online (Sandbox Code Playgroud)

在.示例我的字符串"银行Flamwood C2"有​​通过指针获取值的方法(在GDALRATGetValueAsString方法中使用):

var pointer = GDALRATGetValueAsString(GDALRasterAttributeTableH, row, field);
    a)    var b = Marshal.PtrToStringUni(pointer);       // value: "??????2"
    b)    var a = Marshal.PtrToStringAnsi(pointer);      // value: "??Flamwood C2"
    c)    var c = Marshal.PtrToStringAuto(pointer);      // value: "??????2"
    d)    var d = Marshal.PtrToStringBSTR(pointer);       //Throws an error out of memory.
Run Code Online (Sandbox Code Playgroud)

问:所以如何保存Unicode字符串(所以我可以使用这个Marshal.PtrToStringUni(指针))或者很可能如何将Unicode字符串保存到GDALRAT(GDAL RAT - GDAL栅格属性表)?

GDAL版本:1.11.1

我试图设置CharSet = CharSet.Unicode但id没有帮助,仍然得到不正确的字符串:

[DllImport(GdalWrapper.GdalDLL, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)] 
private static extern void GDALRATSetValueAsString(IntPtr handle, int row, int field, [In][MarshalAs(UnmanagedType.LPStr)] string value); 
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助.

PS如果需要再次构建GDAL源文件以将字符串保存为unicode字符串,那么必须设置哪些构建参数和位置?

小智 3

GDAL 在处理字符串时在内部使用 UTF-8 编码。这意味着字符串在传递给 GDAL 之前必须转换为 UTF-8。这对于 GDAL 输出字符串同样有效 - 在使用之前必须从 UTF-8 转换为本地编码。

C# 使用 UTF-16 字符串,因此必须引入与 UTF-8 之间的转换:

public class EncodingConverter
{
    public static string Utf16ToUtf8(string utf16String)
    {
        byte[] utf16Bytes = Encoding.Unicode.GetBytes(utf16String);
        byte[] utf8Bytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, utf16Bytes);
        return Encoding.Default.GetString(utf8Bytes);
    }

    public static string Utf8ToUtf16(string utf8String)
    {
        byte[] utf8Bytes = Encoding.Default.GetBytes(utf8String);
        byte[] utf16Bytes = Encoding.Convert(Encoding.UTF8, Encoding.Unicode, utf8Bytes);
        return Encoding.Unicode.GetString(utf16Bytes);
    }
}
Run Code Online (Sandbox Code Playgroud)

回到您的问题,如果应用编码转换,日语字符将被正确处理。

    public void SetValueAsString(int row, int field, string value)
    {
        string utf8Value = EncodingConverter.Utf16ToUtf8(value);
        GDALRATSetValueAsString(GDALRasterAttributeTableH, row, field, utf8Value);
    }

    public string GetValueAsString(int row, int field)
    {
        string value = null;

        var pointer = GDALRATGetValueAsString(GDALRasterAttributeTableH, row, field);
        if (pointer != IntPtr.Zero)
        {
            string utf8Value = Marshal.PtrToStringAnsi(pointer);
            value = EncodingConverter.Utf8ToUtf16(utf8Value);
        }
        return value;
    }
Run Code Online (Sandbox Code Playgroud)