• GDAL C#中文路径,中文属性名称乱码问题


    昨天写的博客,将C#读取shp中文属性值乱码的问题应该可以解决,博客地址为:http://blog.csdn.net/liminlu0314/article/details/54096119,然后又测试发现中文路径,中文属性值如果有中文时,也会出现乱码,具体表现为偶数个汉字没有问题,奇数个汉字会出现乱码。
    继续调试C#的源码,发现问题还是在于将C++库中返回的结果进行编码转换的时候导致的,源码位于OgrPINVOKE.cs文件中。截取原始的代码如下:

      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编码之后再返回应该就没问题了,修改后的代码如下所示:

      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的就没有这个问题。

  • 相关阅读:
    redis分布式锁原理
    设置linux源
    linux 设置固定ip 并且解决ping www.baidu.com不通问题
    java内存模型
    Messenger和MVVM中的View Services
    MVVMLight
    MVVMLight
    MvvmLight
    MVVM 事件转命令1
    Mvvm简介
  • 原文地址:https://www.cnblogs.com/xiaowangba/p/6313894.html
Copyright © 2020-2023  润新知