编译GDAL过程比较繁琐,查阅了网上相关资料,同时经过实践,完成GDAL的编译,同时解决了SHP数据中文路径及中文字段乱码的问题,本文以“gdal-2.3.2”版本为例阐述整个编译过程。函数
1、编译准备工具
一、编译工具是VS2017,编译前须要下载“gdal-2.3.2”和“swigwin-3.0.12”,下载连接以下:测试
二、在“D盘”新建目录“GDAL”,将两个压缩包解压到该目录中,同时新建一个文件夹用于存放编译结果(如“D:\GDAL\GDAL\GDAL232“”),如图所示:this
三、修改“D:\GDAL\gdal-2.3.2\nmake.opt”文件,以下图:spa
文件“nmake.opt”修改以下:.net
2、编译C++code
以管理员运行【开始】-【全部程序】-【Visual Studio 2017】-【Visual Studio Tools】-【VC】-【适用于 VS 2017 的 x64 本机工具命令提示】菜单,弹出命令框如图所示:orm
输入cd D:\GDAL\gdal-2.3.2 切换至gdal-2.3.2目录,如图所示:blog
而后依次输入:接口
C++编译时间较长,须要耐心等待……
3、编译C#
一、修改C#源码文件
打开“D:\GDAL\gdal-2.3.2\swig\csharp\AssemblyInfo.cs”,注释掉【[assembly: AllowPartiallyTrustedCallers]】,以下图所示:
打开以下三个文件:
分别注释掉重复的构造函数,如图所示:
打开以下三个文件:
文件,修改接口成员(大概17行),以下:
public Band(IntPtr cPtr, bool cMemoryOwn, object parent): base(GdalPINVOKE.Band_SWIGUpcast(cPtr), cMemoryOwn, parent){swigCPtr = new HandleRef(this, cPtr);} public Dataset(IntPtr cPtr, bool cMemoryOwn, object parent): base(GdalPINVOKE.Band_SWIGUpcast(cPtr), cMemoryOwn, parent){swigCPtr = new HandleRef(this, cPtr);} public Driver(IntPtr cPtr, bool cMemoryOwn, object parent): base(GdalPINVOKE.Band_SWIGUpcast(cPtr), cMemoryOwn, parent){swigCPtr = new HandleRef(this, cPtr);}
接下来解决读取中文路径及属性乱码 :
打开以下四个文件:
分别修改类“SWIGStringHelper”(大概168行),具体代码(红色为修改过得代码)以下:
protected class SWIGStringHelper { public delegate string SWIGStringDelegate(IntPtr message); static SWIGStringDelegate stringDelegate = new SWIGStringDelegate(CreateString); [global::System.Runtime.InteropServices.DllImport("ogr_wrap", EntryPoint="SWIGRegisterStringCallback_Ogr")] public static extern void SWIGRegisterStringCallback_Ogr(SWIGStringDelegate stringDelegate); static string CreateString(IntPtr pNativeData) { if (pNativeData == IntPtr.Zero) return ""; int i = 0; byte[] strbuf1 = new byte[1]; Marshal.Copy(pNativeData + i, strbuf1, 0, 1); while (strbuf1[0] != 0) { i++; strbuf1 = new byte[1]; Marshal.Copy(pNativeData + i, strbuf1, 0, 1); } int length = i;//循环查找字符串的长度 byte[] strbuf = new byte[length]; Marshal.Copy(pNativeData, strbuf, 0, length); return System.Text.Encoding.UTF8.GetString(strbuf); } static SWIGStringHelper() { SWIGRegisterStringCallback_Ogr(stringDelegate); } }
打开以下三个文件:
分别修改函数“Utf8BytesToString”,代码以下:
internal static string Utf8BytesToString(IntPtr pNativeData) {
if (pNativeData == IntPtr.Zero) return null; int i = 0; byte[] strbuf1 = new byte[1]; Marshal.Copy(pNativeData + i, strbuf1, 0, 1); while (strbuf1[0] != 0) { i++; strbuf1 = new byte[1]; Marshal.Copy(pNativeData + i, strbuf1, 0, 1); } int length = i;//循环查找字符串的长度 byte[] strbuf = new byte[length]; Marshal.Copy(pNativeData, strbuf, 0, length); //int length = Marshal.PtrToStringAnsi(pNativeData).Length; //byte[] strbuf = new byte[length]; //Marshal.Copy(pNativeData, strbuf, 0, length); return System.Text.Encoding.UTF8.GetString(strbuf); }
二、编译
输入cd swig\csharp ,切换到csharp目录,
输入nmake /f makefile.vc(运行这一步有问题的话,加如下两句:namke /f makefile.vc clear 、nmake /f makefile.vc interface)
输入nmake /f makefile.vc install
编译完成后,在目录“D:\GDAL\GDAL\GDAL232\csharp”会生成8个文件,如图所示:
注:C#编译过程当中,若是出现HandleRef和IntPtr没有引用的错误,只须要在相应文件中添加命名空间
using System;
using System.Runtime.InteropServices;便可解决该问题
4、测试DLL
新建一个Winform应用程序,修改运行配置为x64,如图所示:
把“D:\GDAL\GDAL\GDAL232\csharp”中的8个dll和“D:\GDAL\GDAL\GDAL232\bin”中的一个dll复制到“x64/Release”目录下,添加引用
读取Shp数据的代码以下:
OSGeo.GDAL.Gdal.AllRegister(); OSGeo.OGR.Ogr.RegisterAll(); OSGeo.OGR.Driver dr = OSGeo.OGR.Ogr.GetDriverByName("ESRI shapefile"); OSGeo.OGR.DataSource ds = dr.Open(path, 0); if (ds == null) { MessageBox.Show("文件不能打开,请检查!"); return; }
效果如图所示: