zoukankan      html  css  js  c++  java
  • 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的就没有这个问题。

  • 相关阅读:
    【洛谷P3992】开车
    Easyui datagrid+ashx 实现动态生成列
    SQL字符串处理函数大全
    在sqlserver中查找某个字段存在于那个表中的语句
    C# 合并图片
    JavaScript 监听屏幕滑动事件的JS
    JavaScript无提示关闭窗口(兼容IE/Firefox/Chrome)
    使用jquery插件实现图片延迟加载技术
    DataTable随机复制一行给新的DataTable
    MySQL恢复数据报错 #1289 The 'InnoDB' feature is disabled; you need MySQL built with 'InnoDB' to hav
  • 原文地址:https://www.cnblogs.com/xiaowangba/p/6313894.html
Copyright © 2011-2022 走看看