1. 程式人生 > >GDAL2.0編譯之新增HDF庫編譯C#版本

GDAL2.0編譯之新增HDF庫編譯C#版本

        最近一段時間想把專案軟體中使用的GDAL庫升級一下,由於我使用的GDAL庫還是1.8版本的C#版,這個版本對檔案的中文路徑支援方面有些問題想換一個較高的版本進而解決該問題。

        於是從網上下載了GDAL2.01、  HDF1.8.15以及swigwin1.3.40,嘗試利用HDF1.8.16與swigwin3.0.7這兩個高版本的均失敗了目前還沒有找到什麼原因,於是就換成較低的版本來進行。

       本人編譯的為64位的GDAL,環境為Win10 64位、VS2015企業版,GDAL的配置關鍵部分如下:

!IFNDEF MSVC_VER
#assume msvc VS2008.
MSVC_VER=1900
!ENDIF

編譯好的庫儲存路徑
!IFNDEF GDAL_HOME
GDAL_HOME = "D:\lib\GDAL_HDF_x64"
!ENDIF

SWIG路徑,此處為編譯C#版GDAL準備
# Set the location of your SWIG installation
!IFNDEF SWIG
SWIG = D:\lib\swigwin-1.3.40\swig.exe
!ENDIF
編譯64位GDAL
# Uncomment the following if you are building for 64-bit windows
# (x64). You'll need to have PATH, INCLUDE and LIB set up for 64-bit
# compiles.
WIN64=YES
配置HDF5庫
# Uncomment the following and update to enable NCSA HDF Release 5 support.
HDF5_PLUGIN = NO
HDF5_DIR =	D:\lib\HDF5\1.8.15
HDF5_LIB =	$(HDF5_DIR)\lib\hdf5.lib $(HDF5_DIR)\lib\hdf5_cpp.lib

這些都修改好後啟動VS2015 x64本機工具命令提示符




切換到工作目錄下命令為:"D:"回車即可切換到D盤,然後利用cd命令進入工作目錄即可。

下邊就是編譯GDAL C++版本,輸入如下三行命令:

nmake -f makefile.vc

nmake -f makefile.vc install

nmake -f makefile.vc devinstall

如果在輸入第一個命令出現錯誤,很有可能是HDF5庫引起的,我在編譯的過程中就出現了錯誤,解決辦法是將HDF5的include資料夾下的H5pubconf.h檔案開啟,大約在195行有以下兩行程式碼
/* Define to 1 if you have the <inttypes.h> header file. */
#define H5_HAVE_INTTYPES_H 1
將以上兩句程式碼中的第二行即#define這行遮蔽,因為在Windows系統中並沒有inttypes這個定義,修改後程式碼如下
/* Define to 1 if you have the <inttypes.h> header file. */
/*#define H5_HAVE_INTTYPES_H 1*/

然後重新輸入以上三行命令進行編譯,最後即可得到C++版本的GDAL,需要注意的是一定要將HDF5庫中的必要的DLL拷貝到編譯好的bin資料夾下,並且在呼叫該GDAL的時候不能僅將gdal200.dll拷貝的工程目錄下,還需要將HDF5的dll拷貝到工程目錄下,否則程式執行到呼叫GDAL庫的時候會出現錯誤,針對我這個版本的GDAL與HDF5庫,需要拷貝的DLL有如下幾個:



下邊就是編譯C#版的GDAL,編譯很簡單,首先定位到gdal目錄下的csharp資料夾  cd swig/csharp,然後執行以下兩行命令即可

nmake -f makefile.vc interface
nmake -f makefile.vc

在李民錄老師的部落格中看到說第一行命令可以不執行,但是我在操作的過程中如果不執行第一步就會出錯,目前還不知道什麼原因,所以對於我這種情況還是需要執行第一步的。這兩行命令執行完以後會在C++版本的GDAL庫目錄下出現csharp資料夾,該資料夾下會有8個DLL如下圖所示:

這樣C#版的GDAL到此就編譯完成了,但是這並不是關鍵所在,最關鍵的問題是如何呼叫。雖然大家常說這個問題,但是我還是犯了這個錯誤,導致很長一段時間不知道問題所在,在呼叫自己編譯的C#版GDAL總是不成功。在呼叫C#版GDAL的時候,我不常說不要忘了把gdal200.dll拷貝到工作目錄下還有相應其他的庫的dll,我在呼叫的時候將這個八個dll以及gdal200.dll拷貝到了工作目錄下,但是執行過程中出現了錯誤,在呼叫Gdal.AllRegister()這個函式時就出錯了如下圖所示


後來想到是GDAL編譯過程中載入了HDF5庫,因此還需要將HDF5庫的四個dll hdf5.dll、hdf5_cpp.dll、zlib.dll、szib.dll都拷貝到了工作目錄下,再次執行錯誤不見了。但是當我將我的軟體編譯好的Release拷貝到其他人的電腦上執行的時候,GDAL又出現了錯誤,我就很納悶了為什麼在我的電腦上沒問題,到了別人的電腦上就不行了呢。後來思考應該還是dll的問題,在我的電腦上應該已經有這個dll了,而到了其他人的電腦上,沒有這個dll,因此在呼叫GDAL庫的時候就又出現了問題,後來我開始找是哪個dll引起的,最終發現在HDF5庫的bin目錄下有兩個dll即msvcr120.dll與msvcp120.dll,因為我下載的HDF5庫是用高版本的VS編譯的(大概是VS2012或者是VS2013記不清了),因此需要用到這個兩個dll,因為我的電腦上已經有了這兩個dll所以在我的電腦上沒問題,而其他人電腦上如果沒有配置這兩個dll,在軟體呼叫GDAL庫的過程中就會出現問題,最後把這兩個dll拷貝的工作路徑下,問題得到了解決。

最終通過測試,對於我這個版本的GDAL庫,在 呼叫C#的GDAL時需要拷貝的DLL共有如下13個dll(GDAL編譯過程中新增的第三方庫越多,這裡需要用到的DLL也越多)


在以後呼叫過程中,將這些dll拷貝到工作目錄下,在工程中載入帶有csharp字元的dll到引用中即可成功呼叫C#版的GDAL