Catching PINVOKE exception from loaded assembly


#1

Hi @Alain, @dale, @stevebaer, @will

I am trying call a method from loaded .NET assembly in python, but for some reason, I am getting a PINVOKE exception. Is there some way to print what is the reason for that exception? This looks like a similar topic, but I am not sure how it can be replicated in ironpython.

This is the code:

import clr
clr.AddReferenceToFileAndPath("c:/gdal/gdal2bb/gdal_csharp.dll")

import OSGeo.GDAL as gdalc

gdalc.Gdal.AllRegister()

Last line raises:

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

I am essentially trying to open the file by replicating this c++ example:

#include "gdal_priv.h"
#include "cpl_conv.h" // for CPLMalloc()

int main()
{
    GDALDataset  *poDataset;

    GDALAllRegister();

    poDataset = (GDALDataset *) GDALOpen( pszFilename, GA_ReadOnly );
    if( poDataset == NULL )
    {
        ...;
    }

What is the reason for the raised PINVOKE exception?

Dale showed me how to check whether or not the loaded assembly is .NET or not. And it is. Further more the following code prints: True:

importedAssembly = "gdal_csharp" in [assembly.GetName().Name for assembly in clr.References]
print "importedAssembly: ", importedAssembly   # prints: True

I have a 32 bit windows XP SP3 operating system and loaded gdal_csharp.dll is 32 bit compiled, download​ed from gisinternals.com. I attached gdal_csharp.dll and all other its .dlls in here. I am using Rhino 5 (5.12.50810.13095, 08/10/2015).
This is the gdal documentation page.

I contacted gdal mailing list, and got a reply, that this might be something related with Rhino, not with .NET assemblies.

Any help would be appreciated.
Thank you.


(Menno Deij - van Rijswijk) #2

The nice thing, I guess, is that you can look in the code because it is open (see http://trac.osgeo.org/gdal/wiki/DownloadSource). Also, the exception should have a message that could maybe help you find out what is going on.

try:
    gdalc.Gdal.AllRegister()

except System.Exception as e:
    print e.Message


#3

Thank you for the reply Menno.

I am getting the same upper exception printed:

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

I can see you downloaded the gdal_csharp.zip file.
Did you by any chance try to run the upper code?


(Menno Deij - van Rijswijk) #4

I’m not at my computer currently. Also, I only have 64-bit Rhino…


#5

There are 64 bit compiled gdal .dlls also. They are located in:

release-1600-x64-gdal-1-11-1-mapserver-6-4-1.zip \ bin \ gdal \ csharp


(Menno Deij - van Rijswijk) #6

You need not only the files in the csharp folder, but also all the dll’s that are directly in the bin folder. These need all to be in the same place.
I’ve tried this with a C# plug-in, not with Python script, but I also first got the PInvoke error. After adding all the DLL’s from the bin folder, the exception went away.

How did I go about this? First, the PInvoke exception has an inner exception, whose message is “unable to load DLL gdal_wrap”. Then I used the Depends utility to see which DLLs gdal_wrap depends on. It said it could not find gdal111.dll. This was in the folder bin. So I copied all DLL’s from the bin folder to the plug-in folder and the exception was no longer generated.

I hope this works for you as well.


#7

Thank you for both the solution and detailed explanation Menno. That worked perfectly!
It is interesting that once I copied all the .dlls from the “bin” folder, an exception remained. I had to restart Rhino 5, before the exception went away.

Greetings to the lovely Netherlands.


(Felipegutierrezduque10) #8

@Alain, @dale, @stevebaer, @will I am experiencing the same problem with the same library, and the solution given by @menno doesn’t work in my case, I have tried to copy the dll’s inside the same folder as the plugin and after encapsulating the:

GdalConfiguration.ConfigureOgr();

GdalConfiguration.ConfigureGdal();

calls in a try catch, I am seeing:

Exception caught. System.TypeInitializationException: Se produjo una excepción en el inicializador de tipo de 'ReadGribFiles.GdalConfiguration'. ---> System.TypeInitializationException: Se produjo una excepción en el inicializador de tipo de 'OSGeo.GDAL.GdalPINVOKE'. ---> System.TypeInitializationException: Se produjo una excepción en el inicializador de tipo de 'SWIGExceptionHelper'. ---> System.DllNotFoundException: No se puede cargar el archivo DLL 'gdal_wrap': No se puede encontrar el módulo especificado. (Excepción de HRESULT: 0x8007007E)
   en OSGeo.GDAL.GdalPINVOKE.SWIGExceptionHelper.SWIGRegisterExceptionCallbacks_Gdal(ExceptionDelegate applicationDelegate, ExceptionDelegate arithmeticDelegate, ExceptionDelegate divideByZeroDelegate, ExceptionDelegate indexOutOfRangeDelegate, ExceptionDelegate invalidCastDelegate, ExceptionDelegate invalidOperationDelegate, ExceptionDelegate ioDelegate, ExceptionDelegate nullReferenceDelegate, ExceptionDelegate outOfMemoryDelegate, ExceptionDelegate overflowDelegate, ExceptionDelegate systemExceptionDelegate)
   en OSGeo.GDAL.GdalPINVOKE.SWIGExceptionHelper..cctor()
   --- Fin del seguimiento de la pila de la excepción interna ---
   en OSGeo.GDAL.GdalPINVOKE.SWIGExceptionHelper..ctor()
   en OSGeo.GDAL.GdalPINVOKE..cctor()
   --- Fin del seguimiento de la pila de la excepción interna ---
   en OSGeo.GDAL.GdalPINVOKE.SetConfigOption(String jarg1, String jarg2)
   en OSGeo.GDAL.Gdal.SetConfigOption(String pszKey, String pszValue)
   en ReadGribFiles.GdalConfiguration..cctor()
   --- Fin del seguimiento de la pila de la excepción interna ---
   en ReadGribFiles.GdalConfiguration.ConfigureOgr()
   en ReadGribFiles.ReadGribFiles.SolveInstance(IGH_DataAccess DA)

Fail to load .dll in grasshopper component
(Steve Baer) #9

I don’t have any experience with library, so won’t be of a whole lot of use. Are you making sure to use the 64 bit DLLs that djordje posted a link to earlier in this thread? Otherwise, you may have to contact the authors of the GDAL library.


(Felipegutierrezduque10) #10

I finally managed to do what I wanted the trick is to have the dll’s your plugin depends on inside the:
C:\Program Files\Rhinoceros 5 (64-bit)\System folder.
I didn’t use any of the dll’s posted by djordje, I used the ones from the nuget package.
I guess that the problem is that Rhino runs all their plugins in a sand-box fashion, so by having the dll’s in the Rhino.exe folder you can access them outside the sandbox, but I don’t really know, anybody with more experience can clarify, please?