2015-10-23 16 views
10

私はGDALの助けが必要です。中国記号の文字列値が正しく読み込まれたり保存されたりしません(C#)。我々が使用SAVINGグリッド値についてGDAL GDALRATSetValueAsString()中国語の文字を保存する方法(C#)?


プライベート静的にexternボイドGDALRATSetValueAsStringを(のIntPtrは、文字列値[MarshalAs(UnmanagedType.LPStr)] [IN] INT列、int型のフィールドを、ハンドル)。文字列値を保存するには メソッド(C#)を使用すると、このメソッドは文字列をANSI文字列として保存するようです。読書のための

private static extern IntPtr GDALRATGetValueAsString(IntPtr handle, int row, int field); 

で。例私の文字列「银行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. 

Q:それでは、どのように私はUnicode文字列を取得することができます保存されていた(ので、私が使用して得ることができますこのMarshal.PtrToStringUni(ポインタ))またはおそらくユニコード文字列を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); 

感謝を。

P.S.文字列をUnicode文字列として保存するには、GDALソースファイルを再度ビルドする必要がある場合は、どのビルドパラメータを設定する必要がありますか?

+1

このリンクはhttps://trac.osgeo.org/gdal/wiki/rfc5_unicodeにあります。たぶん、簡単な方法があります(この記事は5年前に書かれました...)? – Drasius

+0

またチケットを作成しました:https://trac.osgeo.org/gdal/ticket/6168#ticket – Drasius

+0

あなたの解決策を貼り付けてください –

答えて

2

GDALは、文字列の操作時に内部的にUTF-8エンコーディングを使用します。つまり、GDALに渡す前に文字列をUTF-8に変換する必要があります。同じことがGDAL出力文字列にも有効です。使用する前にUTF-8からローカルエンコーディングに変換する必要があります。

C#がUTF-8とバックへの変換が導入されなければならないので、UTF-16文字列を使用します:エンコード変換が適用される場合は、あなたの問題に戻って

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); 
    } 
} 

は、日本語の文字が正しく処理されます。

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; 
    } 
0

この最初にお読みくださいSpecifying a Character Set。 GDALRATGetValueAsStringのUnicode版があることを確認してください。 ユニコードのバージョンはWで終わります。 GDALRATGetValueAsStringW。 ANSIバージョンは、Aで終わります。 GDALRATGetValueAsStringA。 GDALRATGetValueAsStringをインポートすると、charsetはautoになります。 参照している関数のバージョンが不明です。

+1

C APIのAPIを見てくださいhttp://www.gdal。org/gdal_8h.html const char *なので返されるANSI文字列のようです。 ANSI文字列をUnicodeに変換するには、ラッパー関数が必要です。例えば。 MultiByteToWideChar https://msdn.microsoft.com/en-us/library/windows/desktop/dd319072(v=vs.85).aspx –

関連する問題