VS编译GDAL
做GIS开发的,如果不会用GDAL,难免会遭人嘲笑,但作为一个只会C#的业余GIS开发者,GDAL的C++源码就然并卵了,虽然.net环境可以调用C++的dll,但要命的是,学C#的一般不会编译,所以就只能用别人编译好的dll了,实际上gdal官网也指了一条明路,http://trac.osgeo.org/gdal/wiki/DownloadingGdalBinaries这个页面就专门罗列了各种现成的资源,对于.net开发人员来讲,GISInternals是一个好去处,但这个网站上维护的dll库有一个很大的问题,就是功能很全面,导致依赖的第三方dll也更多,但我们实际上很可能都用不上,却不得不都引用到程序中,对于有dll洁癖的人来说,决不能容忍。当然,国内也有很多人分享了自己的编译成果,但鱼目混珠,而且一般编译的版本比较老,导致很多gdal的新功能用不上,只能干着急。那就自己动手,丰衣足食吧,好在gdal的编译难度其实很低,官网也给出了较为翔实的指导,另外网上也有很多可以学习的成功案例,本文就是结合gdal官网的帮助和网上的各路资源做的一个总结,以备日后查用。
1 准备工作
gdal官网下载源码,准备好编译工具,对于.net开发人员来讲,vs肯定最为熟悉了,但只会C#的童鞋,在安装vs时,可能就只选了C#这一种语言,那就悲剧了,因为压根就没有C++环境,最基础的C++库文件都没有,如何编译呢,所以这里重要的事说三遍,必须是安装了VC++的VS才能进行编译。
此外,由于后面要在C#程序中调用,C#的接口dll也是少不了要编译的,这个需要借助swig,所以下载一个swig也是必不可少的,需要的版本可以参考gdal官网:http://trac.osgeo.org/gdal/wiki/GdalOgrCsharpCompile
然后就是修改nmake.opt文件,主要有两处,一处是GDAL_HOME,指定源码所在文件夹,一般建议将文件夹的名称改成gdal,并且放在C盘根目录下,这样可方便后面操作,另外一处是90行,swig.exe的路径,可先将下载后swig程序包解压到C盘,就可以获得swig.exe所在位置的绝对路径。
除此之外,由于gdal1.8后增加了对路径是否为UTF8编码的判断,直接编译后获得的exe程序不支持中文路径,在利用命令行调用原生exe处理数据时,有一些麻烦,这里可以在编译前通过修改源码来解决这个问题。将下面一句
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO");
分别添加到GDALAllRegister()函数【GDAL_HOME\frmts\gdalallregister.cpp73行左右】和OGRRegisterAll()函数【GDAL_HOME\ogr\ogrsf_frmts\generic\ogrregisterall.cpp38行左右】中。
2 编译gdal.dll
从windows开始菜单的vs应用程序文件夹中打开visual stuido 命令提示,然后先后输入以下三行命令,即可完成gdal.dll和原生exe的编译,编译结果在bin文件夹中。
nmake /f makefile.vc
nmake /f makefile.vc install
nmake /f makefile.vc devinstall
3 编译.net dll
首先找到swig/csharp文件夹,gdal已经提供了接口的cs代码文件,但存一些问题,在编译时可以发现,这里在编译前解决。
问题1、接口重定义
osr\OsrPINVOKE.cs(192,10): error CS0111: 类型“OSGeo.OSR.OsrPINVOKE”已定义了一个名为“OsrPINVOKE”的具有相同参数类型的成员
osr\OsrPINVOKE.cs(188,10): (与前一个错误相关的符号位置) NMAKE : fatal error U1077: “C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.EXE”: 返回代码“0x1”
解决办法:进入到..\gdal-1.9.2\swig\csharp\gdal|ogr|osr三个文件夹下,找到GdalPINVOKE.cs、OgrPINVOKE.cs、OsrPINVOKE.cs,将提示中重复的参数类型删除掉即可,错误示例如下图:

问题2:接口成员名称调用错误,错误提示:
gdal\Band.cs(17,79): error CS0117: “OSGeo.GDAL.GdalPINVOKE”并不包含“BandUpcast”的定义
gdal\Dataset.cs(17,82): error CS0117: “OSGeo.GDAL.GdalPINVOKE”并不包含“DatasetUpcast”的定义
gdal\Driver.cs(17,81): error CS0117: “OSGeo.GDAL.GdalPINVOKE”并不包含“DriverUpcast”的定义
NMAKE : fatal error U1077: “C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.EXE”: 返回代码“0x1”
GdalPINVOKE.cs定义接口如下:

Band类(举一例)调用如下:

将三个类中的接口修改一下即可:
public Driver(IntPtr cPtr, bool cMemoryOwn, object parent) : base(GdalPINVOKE.Driver_SWIGUpcast(cPtr), cMemoryOwn, parent) { swigCPtr = new HandleRef(this, cPtr);
public Dataset(IntPtr cPtr, bool cMemoryOwn, object parent) : base(GdalPINVOKE.Dataset_SWIGUpcast(cPtr), cMemoryOwn, parent) { swigCPtr = new HandleRef(this, cPtr);
public Band(IntPtr cPtr, bool cMemoryOwn, object parent) : base(GdalPINVOKE.Band_SWIGUpcast(cPtr), cMemoryOwn, parent) { swigCPtr = new HandleRef(this, cPtr);
问题3 安全透明方法问题
在以上两个问题解决后,编译后生成的csharp dll在调用时会出下如下错误:
“安全透明方法“OSGeo.GDAL.Gdal.AllRegister()”尝试通过方法“OSGeo.GDAL.GdalPINVOKE.AllRegister()”调用本机代码失败。方法必须是安全关键的或安全可靠关键的”
要解决这个问题,需要在编译GDAL的C#版本时,修改csharp目录中的AssemblyInfo.cs文件。具体修改如下:
// The AllowPartiallyTrustedCallersAttribute requires the assembly to be signed with a strong name key.
// This attribute is necessary since the control is called by either an intranet or Internet
// Web page that should be running under restricted permissions.
//[assembly: AllowPartiallyTrustedCallers] 注释掉这一行
以上三个问题都解决了,仍然在vs的命令行中,先通过cd命令定位到swig/csharp文件夹,然后输入命令
C:\GDAL\swig\csharp> nmake /f makefile.vc
即可得到C#开始所需要的8个dll,4个_csharp,4个_wrap


浙公网安备 33010602011771号