GDAL C#中文路徑,中文屬性名稱亂碼問題

昨天寫的博客,將C#讀取shp中文屬性值亂碼的問題應該能夠解決,博客地址爲:http://blog.csdn.net/liminlu0314/article/details/54096119,而後又測試發現中文路徑,中文屬性值若是有中文時,也會出現亂碼,具體表現爲偶數個漢字沒有問題,奇數個漢字會出現亂碼。
繼續調試C#的源碼,發現問題仍是在於將C++庫中返回的結果進行編碼轉換的時候致使的,源碼位於OgrPINVOKE.cs文件中。截取原始的代碼以下:c#

protected class SWIGStringHelper {

    public delegate string SWIGStringDelegate(string message);
    static SWIGStringDelegate stringDelegate = new SWIGStringDelegate(CreateString);

    [DllImport("ogr_wrap", EntryPoint="SWIGRegisterStringCallback_Ogr")]
    public static extern void SWIGRegisterStringCallback_Ogr(SWIGStringDelegate stringDelegate);

    static string CreateString(string cstring) //這個函數出問題
    {
        return cstring;
    }

    static SWIGStringHelper() {
      SWIGRegisterStringCallback_Ogr(stringDelegate);
    }
  }

出問題的函數在於CreateString,這個函數是一個相似C的回掉函數,直接將C庫中返回的const char*直接轉爲C#中的string進行返回,這樣的結果就是若是C庫中的const char*以UTF8編碼的話,直接返回的就是亂碼,而且可能致使截斷。因此就表現爲圖層名亂碼,屬性字段名亂碼等問題。
解決方案與昨天處理的相似,將C庫中的const char*用UTF8編碼以後再返回應該就沒問題了,修改後的代碼以下所示:markdown

protected class SWIGStringHelper {

    public delegate string SWIGStringDelegate(IntPtr message);//此處修改參數類型
    static SWIGStringDelegate stringDelegate = new SWIGStringDelegate(CreateString);

    [DllImport("ogr_wrap", EntryPoint="SWIGRegisterStringCallback_Ogr")]
    public static extern void SWIGRegisterStringCallback_Ogr(SWIGStringDelegate stringDelegate);

    static string CreateString(IntPtr pNativeData)//此處函數內容須要修改
    {
        if (pNativeData == IntPtr.Zero)
            return "";

        //下面這一長串就是獲取C字符串的長度,用Marshal庫中的函數獲取的都有問題,因此就用下面的循環來本身找了,若是有更好的方案請告知。
        int nAnsiLength = Marshal.PtrToStringAnsi(pNativeData).Length;
        int nUniLength = Marshal.PtrToStringUni(pNativeData).Length;
        int nMaxLength = (nAnsiLength > nUniLength) ? nAnsiLength : nUniLength;
        int length = 0;
        for (int i = 0; i < nMaxLength; i++)
        {
            byte[] strbuf1 = new byte[1];
            Marshal.Copy(pNativeData + i, strbuf1, 0, 1);
            if (strbuf1[0] == 0)
            {
                break;
            }
            length++;
        }

        byte[] strbuf = new byte[length];
        Marshal.Copy(pNativeData, strbuf, 0, length);
        return System.Text.Encoding.UTF8.GetString(strbuf);
    }

    static SWIGStringHelper() {
      SWIGRegisterStringCallback_Ogr(stringDelegate);
    }
  }

修改完保存,一樣的問題有4個文件,分別是OgrPINVOKE.cs、GdalPINVOKE.cs、OsrPINVOKE.cs和GdalConstPINVOKE.cs。 將這四個文件中SWIGStringHelper類中的內容都按照上面這樣修改,而後從新生成dll,便可。函數

PS:上面的修改完以後,調試時沒有問題,直接運行的時候最後一個漢字可能會丟失,問題很奇怪,不知道爲啥。測試

編譯好的庫已經上傳,下載地址爲:http://download.csdn.net/detail/liminlu0314/9730475
PS:通過測試,發現上面丟失最後一個漢字的問題已經解決,以前是debug的版本,用release的就沒有這個問題。編碼

相關文章
相關標籤/搜索