简介这份资源是作者在 Windows 下基于 msys2 mingw64 方式预先编译好的 GDAL 1.11.5 库面向使用 QtMinGW 版进行 C 地理信息开发的工程师与学习者省去自行编译 GDAL 的繁琐过程。压缩包共 149 个文件约 70.71MB包含 63 个 h 头文件、22 个 exe 工具、28 个 csv 坐标与投影数据、8 个 gfs、6 个 wkt 及若干 svg、dxf、dgn、xml、xsd 等另有 libgdal.a、libgdal.dll.a 等静态与导入库覆盖头文件、可执行工具与数据资源结构完整。已有 1520 人学习下载。解压后将 bin 目录加入系统环境变量并在 .pro 文件中配置 GDAL 即可直接调用适合需要快速搭建 GIS 开发环境、验证矢量栅格读写与坐标转换功能的读者遇到程序异常结束也可参考作者提供的排错思路定位问题。1. 为什么今天还有人折腾 GDAL 1.11.5 的 MinGW64 编译如果你在 Windows 上做 C 桌面端 GIS 开发大概率绕不开一个组合Qt 做界面、GDAL 读空间数据、MinGW 做编译器。而 GDAL 1.11.5 这个版本虽然年头不短却因为 API 稳定、依赖相对干净至今仍被不少存量项目锁死。问题在于官方预编译包基本是 MSVC 版本直接拿到 MinGW64 工程里链接轻则符号找不到重则运行时堆栈错乱。于是“用 MinGW64 自己编一份 GDAL 1.11.5”就成了很多人绕不过去的一道坎。这份资源就是一份已经用 MinGW64 编译通过的 GDAL 1.11.5 产物包含头文件、静态库/导入库以及配套的依赖目标很明确让 Qt MinGW 的 C 工程能直接把它挂上去用而不是花两天时间跟编译错误死磕。适合谁手上是 Qt 5.x MinGW 套件、需要读写 Shapefile/GeoTIFF、又不打算升级到 GDAL 3.x 的从业者。2. 先搞清楚这份 MinGW64 产物里到底有什么2.1 目录结构与关键文件识别拿到一份编译产物第一件事不是急着往工程里塞而是先看清楚它给了什么。常见的目录组织是include/、lib/、bin/三件套外加一个share/gdal放数据文件。下面这张表是我拆包时习惯先过一遍的清单你可以对照手里的资源核对。路径内容用途include/gdal/gdal.h、gdal_priv.h、ogr_api.h等编译期头文件lib/libgdal.a静态库静态链接时使用lib/libgdal.dll.a导入库动态链接 MinGW 风格bin/libgdal-1.dll运行时动态库程序启动时加载share/gdal/gcs.csv、pcs.csv、data/坐标系统与投影定义bin/gdalinfo.exe命令行工具验证编译是否可用这里有个容易忽略的点MinGW 的导入库后缀是.dll.a不是 MSVC 的.lib。如果你在.pro里写了LIBS -lgdal链接器找的是libgdal.dll.a或libgdal.a命名对不上就会报cannot find -lgdal。先确认文件名再决定链接写法。2.2 动态链接与静态链接的取舍GDAL 1.11.5 在 MinGW64 下动态链接和静态链接的体验差别很大。动态链接的好处是编译快、产物小但部署时必须把libgdal-1.dll和它依赖的一串 DLL比如libproj、libgeos、libtiff、libjpeg等一起拷到 exe 旁边漏一个就是启动即崩。静态链接则相反编译期要把所有依赖都链进去命令长、容易缺符号但最终 exe 自包含拷走就能跑。我一般会这样判断如果项目只是内部工具、部署环境可控动态链接省事如果要发给不特定用户、又不想写安装脚本静态链接更稳。这份资源同时提供了.a和.dll.a说明两种方式都留了口子。下面是一个典型的 qmake 动态链接配置# 在 .pro 文件中配置 GDAL 动态链接 INCLUDEPATH $$PWD/third_party/gdal/include LIBS -L$$PWD/third_party/gdal/lib -lgdal # 部署时把 bin 下的 DLL 拷到输出目录 # 常见做法是用 QMAKE_POST_LINK 自动拷贝 QMAKE_POST_LINK $$quote(cmd /c copy /y $$PWD/third_party/gdal/bin/*.dll $$OUT_PWD/release/)这段配置里INCLUDEPATH指向头文件根目录LIBS的-L指定库搜索路径、-lgdal让链接器去找libgdal.dll.a。QMAKE_POST_LINK是 qmake 的构建后钩子用cmd /c copy把 DLL 批量拷到输出目录省得每次手动复制。注意路径里的$$PWD是.pro所在目录$$OUT_PWD是构建输出目录两者不要混。提示如果你的 MinGW 是 64 位务必确认资源里的库也是 64 位。32 位库链 64 位目标会直接报file format not recognized这个错误信息很有迷惑性容易被当成路径问题。3. 把 GDAL 挂进 Qt 工程从编译到跑通第一个读取程序3.1 编译期配置与常见链接错误配置好.pro之后先别写业务代码用一个最小程序验证链接是否通过。下面这段代码只做一件事注册所有驱动、打开一个 Shapefile、打印图层名。它能跑通说明头文件、库、DLL 三者都对上了。// main.cpp - 最小验证程序 #include gdal_priv.h #include ogrsf_frmts.h #include QDebug int main(int argc, char *argv[]) { // 注册 GDAL 全部驱动1.11.5 必须手动调用 GDALAllRegister(); OGRRegisterAll(); // 以只读方式打开数据源 GDALDataset *poDS (GDALDataset*)GDALOpenEx( test.shp, GDAL_OF_VECTOR, nullptr, nullptr, nullptr); if (poDS nullptr) { qDebug() 打开失败检查路径与驱动; return -1; } // 遍历图层并输出名称 int nLayers poDS-GetLayerCount(); for (int i 0; i nLayers; i) { OGRLayer *poLayer poDS-GetLayer(i); qDebug() 图层: poLayer-GetName(); } GDALClose(poDS); return 0; }逻辑说明GDALAllRegister()和OGRRegisterAll()在 1.11.5 里是必须的不调用的话GDALOpenEx会因为找不到驱动而返回空。GDALOpenEx的第二个参数GDAL_OF_VECTOR表示按矢量数据打开读栅格要换成GDAL_OF_RASTER。参数nullptr依次是允许的驱动列表、打开选项、以及空间参考过滤初学阶段保持默认即可。参数说明GDAL_OF_VECTOR和GDAL_OF_RASTER可以按位或组合同时读矢量和栅格时写GDAL_OF_VECTOR | GDAL_OF_RASTER。GDALClose在 1.11.5 里接受GDALDataset*不要用delete否则可能重复释放。链接阶段最常见的三个错误undefined reference to GDALAllRegister说明库没链上检查-lgdal和路径cannot find -lgdal说明库文件名不匹配确认是libgdal.dll.aerror: gdal_priv.h: No such file说明INCLUDEPATH少了一层GDAL 的头文件通常在include/gdal/下但代码里写的是#include gdal_priv.h所以INCLUDEPATH要指到include/gdal而不是include。3.2 运行时 DLL 依赖与坐标数据路径编译通过只是第一步运行时还有两个坑等着。第一个是 DLL 依赖libgdal-1.dll本身依赖libproj、libtiff、libjpeg、libpng、zlib等一串库这些 DLL 必须和libgdal-1.dll在同一目录或者在任何PATH能找到的地方。用 Dependency Walker 或objdump -p libgdal-1.dll | grep DLL可以列出全部依赖逐个补齐。第二个是坐标数据路径。GDAL 读投影信息时要找gcs.csv、pcs.csv这些文件默认会去编译时写死的路径找换台机器就失效。解决办法是运行时设置GDAL_DATA环境变量# 在程序启动前设置Windows 下用 _putenv _putenv(GDAL_DATAC:/path/to/share/gdal); # 或者在 Qt 里用 qputenv qputenv(GDAL_DATA, C:/path/to/share/gdal);GDAL_DATA指向share/gdal目录里面要有gcs.csv、pcs.csv、coordinate_axis.csv等文件。不设置的话读带投影的 Shapefile 时GetProjectionRef()会返回空字符串或者报Unable to open EPSG support file gcs.csv。这个错误不会让程序崩但会让坐标转换静默失败属于典型的“玄学”问题——数据能读出来坐标就是不对。注意GDAL_DATA的路径不要用反斜杠GDAL 内部按 POSIX 风格解析C:\path\to可能被当成转义序列。统一用正斜杠或双反斜杠。4. 避坑排查MinGW64 编译 GDAL 1.11.5 的五个血泪经验4.1 现象链接时报大量 undefined reference原因MinGW 的链接顺序敏感-lgdal必须放在使用它的目标文件之后。如果.pro里LIBS写在SOURCES前面或者手动写 g 命令时把-lgdal放前面链接器会先处理库、后处理目标文件导致符号找不到。解决qmake 里LIBS的位置一般没问题手动编译时确保-lgdal在.o文件之后。另外确认没有同时链 MSVC 版本的.lib两种格式混用会报incompatible或直接忽略。4.2 现象程序启动即崩无任何输出原因libgdal-1.dll依赖的某个 DLL 缺失Windows 加载器在解析导入表时失败进程直接终止连main都进不去。解决用objdump -p libgdal-1.dll | findstr DLL Name列出全部依赖逐个确认在 exe 目录或PATH中。常见缺失的是libproj-0.dll、libtiff-5.dll、zlib1.dll。用 Process Monitor 过滤LoadImage事件也能快速定位。4.3 现象读 Shapefile 报 “Unable to open EPSG support file”原因GDAL_DATA没设置或者指向的目录里缺少gcs.csv。解决确认share/gdal目录存在且包含gcs.csv然后在main函数最开头用qputenv设置。注意设置必须在GDALAllRegister()之前否则驱动初始化时已经尝试读取过。4.4 现象中文路径读不了原因GDAL 1.11.5 在 Windows 下默认用fopen打开文件不支持 UTF-8 中文路径。MinGW 的运行时对宽字符支持也有限。解决常见做法是把中文路径转成短路径8.3 格式再传给 GDAL或者用GetShortPathNameW转换。另一个办法是升级到 GDAL 3.x但那就偏离了这份资源的使用场景。如果必须用 1.11.5建议工程内部统一用英文路径中文只做显示。4.5 现象静态链接后 exe 体积巨大且启动慢原因静态链接把整个 GDAL 和所有依赖都塞进 exe体积上百 MB 很正常启动时还要初始化大量驱动。解决如果只是读 Shapefile可以在GDALAllRegister()后调用GDALDestroyDriverManager()之前用GDALGetDriverByName只注册需要的驱动减少初始化开销。但 1.11.5 的驱动注册机制比较粗实际收益有限。更现实的做法是接受体积或者改回动态链接。5. 进阶技巧用 gdalinfo 验证产物完整性并锁定驱动版本拿到一份编译产物在写任何业务代码之前我习惯先用它自带的gdalinfo.exe跑一遍确认库本身是健康的。这一步能提前暴露大部分依赖和配置问题比在 Qt 工程里调试快得多。# 查看 GDAL 版本与编译信息 gdalinfo --version # 列出所有已注册驱动确认 Shapefile/GeoTIFF 在列 gdalinfo --formats # 对一个测试文件输出元数据验证读取链路 gdalinfo test.tif--version会输出类似GDAL 1.11.5, released 2016/01/26的信息确认版本没错。--formats列出驱动重点看ESRI Shapefile和GTiff是否存在如果缺失说明编译时没开对应选项。gdalinfo test.tif会打印栅格尺寸、投影、波段数能跑通说明GDAL_DATA和依赖 DLL 都就位了。如果gdalinfo本身都跑不起来报缺 DLL那就别急着往 Qt 里集成先把 DLL 补齐。如果gdalinfo能跑但--formats里没有你需要的格式说明这份产物在编译时裁剪了驱动得换一份或者自己重编。还有一个验证技巧用ogrinfo检查矢量驱动。ogrinfo --formats和gdalinfo --formats在 1.11.5 里输出基本一致但ogrinfo对矢量数据的支持更直接。跑ogrinfo test.shp能列出图层名、几何类型、字段定义确认 OGR 部分也正常。从那以后我每次拿到一份 GDAL 编译产物都强制先跑一遍gdalinfo --version和gdalinfo --formats再动工程配置。这个习惯帮我省掉了至少三次“编译通过但运行时找不到驱动”的返工。希望帮到你。本文还有配套的精品资源点击获取