在使用C#中的GDAL时出现异常

18

我开始在我的应用程序中使用 gdal_csharp dll 并读取一个 geotiff 文件,但它显示:

The type initializer for 'OSGeo.GDAL.GdalPINVOKE' threw an exception.

这是我的代码

string fileName = @"/path to geotiff file";

OSGeo.GDAL.Dataset DS = 
    OSGeo.GDAL.Gdal.Open(fileName, OSGeo.GDAL.Access.GA_ReadOnly);

有人能帮忙吗?

编辑:

我有这些dll文件

图片描述

这是完整的错误信息:

图片描述

它说无法加载 gdal_wrap。但当我尝试将该dll添加到我的应用程序中时,会显示以下消息:

图片描述


1
这段代码是原封不动的,还是你已经给fileName分配了一个真实路径?如果你能提及自己为解决这个问题所做的努力,那会更有帮助。 - Tieson T.
1
由于它是类型初始化程序,它与fileName或调用Open方法无关。首先检查您的依赖项(.net/操作系统版本/库)。 - Ventsyslav Raikov
@Tieson T. 是的,fileName 变量被分配了一个真实路径。 - Hossein Narimani Rad
正如PLB所提到的,似乎缺少一个dll文件,请使用Dependency Walker和Process Monitor来确定是哪个文件。 - Appleman1234
这个问题解决了吗?我在使用VS 2012和GDALInfo.cs时遇到了同样的问题。 - Markus M.
显示剩余2条评论
11个回答

20
作为对此的更新,现在由SharpMap团队维护的GDAL已经成为一个nuget包(这里),并且有定期更新。你需要安装"GDAL.Native"和"GDAL"这两个软件包,以便在项目中使用GDAL库。一旦通过nuget安装,它们会自动创建一个"GdalConfiguration.cs"文件,您可以调用该文件来初始化GDAL路径。唯一要注意的是,这些软件包已设置为自动复制其相应的GDAL库到输出构建目录。如果您需要部署应用程序,则需要做一些额外的努力。

7
是的,就是这样。关键还要安装GDAL.Native。我不知道为什么如果你总是需要这两个东西,他们为什么不把它作为GDAL的一个依赖项。 - Jonas
1
我该如何部署它?部署后我遇到了这个问题。 - tmndungu
2
一旦您安装了GDAL和GDAL.Native,仍然需要调用GdalConfiguration.ConfigureGdal()。 - Corey Alix

5
为了解决这个问题,我按照此处所述下载了预编译库,并从此处获取了FWTools。
我使用的非托管DLL来自\install_dir\FWTools2.4.7\bin,C#包装器来自\install_dir\FWTools2.4.7\csharpgdal14.dllmsvcp71.dllmsvcr71.dll 来自于此处,这也是第一个链接中提到的。
关于 gdal_wrap.dll 的错误提示是指它的某个依赖项。我把那个 DLL 放到 depends 中,它找到了一长串的依赖库。请注意,由于我使用了 FWTools 发行版,因此此列表可能更长 - 如果您是从源代码构建版本,则看起来可能不同,但适用相同的原则。
为了让上述代码在我的计算机上运行,我在输出目录中有以下文件:
gdal14.dll
gdalconst_csharp.dll
gdalconst_wrap.dll
gdal_csharp.dll
gdal_fw.dll
gdal_wrap.dll
geos_fw.dll
geotiff_fw.dll
hdf5dll.dll
hdf_fw.dll
jpeg12_osgeo.dll
jpeg_osgeo.dll
libcurl.dll
libeay32.dll
libexpat.dll
libmysql.dll
libpq.dll
libtiff_fw.dll
lti_dsdk_dll.dll
mfhdf_fw.dll
msvcp71.dll
msvcr71.dll
NCScnet_fw.dll
NCSEcw_fw.dll
NCSUtil_fw.dll
netcdf.dll
ogdi_32b1.dll
proj.dll
sqlite3.dll
ssleay32.dll
szlibdll.dll
xerces-c_2_7.dll
zlib1.dll
zlib_osgeo.dll

现在,这些文件不一定都需要存在于输出目录中,只要它们在你的路径中(例如:\Windows\System32),你就可以正常运行。


5

我知道这是一个老问题,但我相信我的答案可能会帮助某些人。

我能够成功地使用c# gdal编译和运行示例,方法如下:

  1. http://www.gisinternals.com/下载GDAL sdk(我是64位)
  2. 执行SDKShell.bat脚本以设置系统环境路径等
  3. 在Visual Studio中创建一个项目。并引用所有的.net dll文件(名称以_csharp.dll结尾的那些),这些文件位于下载的SDK的\bin\gdal\csharp\
  4. 将Visual Studio项目设置中的平台目标设置为x64以消除错误的图像格式异常。如果我选择使用32位版本的SDK工作,则不需要执行最后一步。

我根本没有安装fwtools。看起来fw_tools的最新版本相对较旧,而sdk仍在维护。


将 Visual Studio 项目设置中的平台目标设置为 x64,这部分对我很有帮助。 - Kliver Max

3

我知道这是一个相当老的问题了,但在自己研究同样的问题后,我在谷歌上找到了这个页面,因此对于搜索此错误的查询来说,这仍然是一个非常相关的页面更新,因为它仍然是从大G中排名前5的。

在我的情况下,"DeusExMachina25"和"Grzegorz Sławecki"的答案引起了共鸣。

我正在编写一些利用NUGet上的"sharp map"当前版本构建的软件(截至2016年6月24日),而我的软件一直抛出与OP最初报告的相同的gdal_wrap消息,尽管我正在使用Sharpmap团队提供的GDAL包。

我没有意识到该包的NUGet安装程序已为我安装了配置类,但在阅读了本主题并发现它确实存在后,我去寻找它。

果然,我在项目中找到了文件'GdalConfiguration.cs',并在适当的位置添加了一个调用,期望正确初始化GDAL。

然而,在我这样做之后,我仍然遇到了同样的问题。

所以,我在已添加的GDAL例程开头设置了断点,并等待直到断点被触发。

然后我跟踪了该方法,并最终找到了以下行:

var gdalPath = Path.Combine(executingDirectory, "gdal");

在文件的第64行左右。

跟踪代码后,我发现正在构建的路径是:

d:\geodata\maptest\maptest\bin\debug\gdal

但是NUGet安装程序已经在其中安装了所有依赖项程序集。
d:\geodata\maptest\maptest\bin\debug

正如我预期的那样,它们位于正确的位置。

我修改了第64行,使其现在读作:

var gdalPath = Path.Combine(executingDirectory, "");

然后,哇,错误消失了,一切开始正常工作。

我也可以采用另一种方式,创建一个名为gdal的文件夹,然后将所有内容复制到其中,但这样会在项目上执行“清理”操作时被删除。

由于config类基于此路径设置各种环境变量,快速更改那一行也可以修复GDAL数据文件、插件和其他一些东西的路径问题。


1

1
您可以尝试使用Dependency Walker查看gdal_csharp正在尝试获取但无法获取的任何dll。

@Appleman1234 - 抱歉,我没有看到您已经建议了那个。 - Cemafor
@Hossein - 尝试将dll手动复制到输出目录,或使用构建事件进行复制,或将其添加到项目中(而不是作为引用),并设置“复制到输出目录”。请参阅此相关问题 - Cemafor
我刚才回顾了你发布的弹出窗口。该dll文件需要放置在exe文件所在的文件夹中,可能是项目中的bin/debug或release子文件夹。 - Cemafor
它仍然在寻找gdal_wrap.dll还是其他的dll? - Cemafor
是的,它仍在寻找gdal_wrap.dll! - Hossein Narimani Rad

0

你忘记了吗:

GdalConfiguration.ConfigureGdal();
GdalConfiguration.ConfigureOgr();

Gdal.AllRegister();
Ogr.RegisterAll();

0

从系统变量中删除Python的路径。因为主要的GDAL路径与Python 27冲突。


0

要使用GDAL的C#绑定,您需要安装FWTools(来自http://fwtools.maptools.org/),以及与您的系统匹配的最新二进制文件(来自http://vbkto.dyndns.org/sdk/)。之后,重要的是将FWTools的bin目录(64位系统的示例:C:\Program Files (x86)\FWTools2.4.7\bin)包含在您的PATH变量中,以及将必要的dlls(问题中提到了gdal_csharp.dll)包含在您的Visual Studio项目引用中。我在这里概述了整个过程。

此过程适用于32位和64位系统,我已在VS 2010和2012上进行了测试。


0
在我的情况下,问题是:
  • 我在解决方案中有两个项目:ProjectAProjectB

  • 我正在执行ProjectA,而ProjectA正在引用ProjectB

  • ProjectB是包含对GDALGDAL.Native的引用的项目

  • ProjectA试图在ProjectA\bin\Debug\netcoreapp3.1\gdal下查找GDAL.Native的文件...但实际上这些文件在ProjectB\bin\Debug\netcoreapp3.1\gdal


可能的解决方案:

  • 不太优雅的解决方案:只需将ProjectB文件复制到ProjectA\bin\Debug\netcoreapp3.1下即可。

  • 较好的解决方案:将GDAL.Native包添加到每个“入口项目”中。


我不喜欢这两个解决方案。这些东西发生在 GdalConfiguration.cs 下面,也许有一种方法可以修改它以找到正确的路径。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接