gdal的編譯比較麻煩,情況有很多種,今天我編譯的gdal遇到的問題就和以前的有點不一樣,僅供參考借鑒。
1、下載gdal源碼
gdal源碼下載地址:https://trac.osgeo.org/gdal/wiki/DownloadSource
已經編譯好的gdal版本下載地址:http://www.gisinternals.com/
我下載的是最新的gdal211,不知道為什么,后面編譯出來的是gdal201的版本。
2、開始編譯C++的開發版本
gdal在window編譯提供的方法:http://trac.osgeo.org/gdal/wiki/BuildingOnWindows
為了編譯64位的gdal,我修改了nmake.opt文件189行處的代碼將#WIN64=YES 改成了WIN64=YES
然后使用cmd設置編譯環境:
call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" amd64
然后進入到gdal目錄,依次執行如下命令:
1、C:\GDAL> nmake /f makefile.vc 2、C:\GDAL> nmake /f makefile.vc install 3、C:\GDAL> nmake /f makefile.vc devinstall
編譯完后會在C盤下面生成warmerda文件夾,里面的文件是用來提供C++編譯的,如下圖:
注意:如果編譯環境設置錯誤,第一步編譯完后會提示如下錯誤:
3、編譯C#使用的版本
編譯C#使用的版本需要借助swig工具,下載地址如下:http://prdownloads.sourceforge.net/swig/swigwin-3.0.10.zip
下載完后解壓,打開nmake.opt,將swig=swig.exe修改成SWIG =E:\swigwin-3.0.10\swig.exe
然后接着上面三句編譯命令之后,進入到swig\csharp目錄下,執行如下命令:
1、nmake /f makefile.vc
2、nmake /f makefile.vc install
注意:在1編譯過程中會出現如下問題:
問題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);
修改完后即可編譯成功,編譯成功之后C:\warmerda\bld文件夾下會生成scharp文件,供C#編程使用。
4、測試程序報錯
問題1、測試程序注冊gdal時出現錯誤
System.MethodAccessException”類型的未經處理的異常出現在 gdal_csharp.dll 中。
其他信息: 安全透明方法“OSGeo.GDAL.Gdal.AllRegister()”嘗試通過方法“OSGeo.GDAL.GdalPINVOKE.AllRegister()”調用本機代碼失敗。方法必須是安全關鍵的或安全可靠關鍵的,才能調用本機代碼。
解決辦法:
修改swig生成的C#封裝類代碼,強制聲明為可被安全透明代碼調用即可,以..\swig\csharp\gdal\Gdal.cs類和..\swig\csharp\gdal\Dataset.cs類為例,在其類聲明的開頭添加下述兩行代碼:
using System.Security; [SecuritySafeCritical]
截圖如下:
如果還出現上面問題,依次添加 [SecuritySafeCritical] 即可。
問題2、測試程序成功之后出現錯誤:
解決辦法,同樣的在Geometry的Dispose方法上加入 [SecuritySafeCritical],如下圖所示
類似的問題解決方法相同。