Problems encountered when calling the gdal library in. Net 4 and Solutions
Recently, you need to call the gdal library in the. NET 4 environment. Gdal itself is a set of unmanaged class libraries, but it also provides a hosted wrapper using swig.
The compiled DLL files of Wrapper can be found in the fwtools installation package. However, the versions included in fwtools depend on gdal_f1_dll (gdal_f1_dll is the modified version of gdal core class library ), while gdal_f1_dll depends on other unmanagedProgramThere are too many sets. The total number is about 18 MB. So download it by yourselfCodeCompiled.
This articleArticleThis section describes the download and compilation methods of version 1.4. This method is also applicable to the latest version 1.7.
After compilation, it is okay to reference, call, and Debug. Everything is normal. However, if you use release to compile and run it outside of Vs, accessviolationexception will be reported, the exception message indicates that the protected memory is accessed. My first response was that the hosted wrapper used P/invoke to call the unmanaged assembly, which caused this problem. However, this speculation does not explain why the error occurs only when the. NET 4 + release + IDE is running.
You can guess and find the problem:
There is a swigstringhelper type in the gdal hosted wrapper. Some important initialization operations are performed in the static constructor of this type. In another class called osrpinvoke, a private static field of the swigstringhelper type is declared, and this field is newly added during the Declaration. In addition, osrpinvoke does not explicitly declare static structures.
To simplify the two types of code, it is probably like this:
View sourceprint? 01 class osrpinvoke
02 {
03 Private Static swigstringhelper helper = newswigstringhelper ();
04
05 public static void dosomething ()
06 {
07 console. writeline ("static method of osrpinvoke ");
08}
09}
10
11 class swigstringhelper
12 {
13 static swigstringhelper ()
14 {
15 // some important Initialization is made here
16 console. writeline ("swigstringhelper static constructor ");
17}
18}
If some code calls dosomething, the execution sequence of the Code is estimated as follows:
Static Construction Method of osrpinvoke (which initializes the static field helper );
Swigstringhelper static Constructor (output string );
Swigstringhelper's instance construction method (nothing in it );
Dosomething method (output string ).
Therefore, swigstringhelperstatic constructor is output first and then static method ofosrpinvoke is output.
Try to call the following code:
View sourceprint? 1 static void main (string [] ARGs)
2 {
3 osrpinvoke. dosomething ();
4 console. Readline ();
5}
However, if the target framework is. net4 and is compiled with release and run outside vs, only static method of osrpinvoke is output. It seems that the static Construction Method of swigstringhelper is not executed. If. NET 2.0 or 3.5 is used, or debug is used for compiling or running in Vs, the output results are the same as expected.
Is the static field initialized in. Net 4 changed to lazy?
Facts prove to be like this:
If a type provides an explicitly declared static structure, this static construction method will be executed before creating an instance of this type or accessing any static members of this type.
If a type does not provide an explicitly declared static structure, the compiler automatically creates a default static structure for the type and places the static field initialization in the default static structure, the default static structure is executed only when the static field is accessed, that is to say, when creating an instance, calling an instance method, or calling a static method, the execution of the static structure is not triggered (the premise is that they do not access static fields ).
However, when loading a type, how does CLR know whether the static constructor included is added by the compiler or explicitly provided by the original C # code? In fact, this is the role of beforefieldinit.
According to the above principles, let's take a look: There is no explicitly declared static structure in osrpinvoke, so the compiler will generate a default static structure and put the creation of the Helper instance into it. The default static structure is executed only when the unique static field helper is accessed. The Code does not have any access to helper, so the static structure of osrpinvoke is not executed at all, and helper is not new at all. The static structure of swigstringhelper is naturally not executed.
To solve this problem, you only need to explicitly declare a static constructor in osrpinvoke and put the new swigstringhelper (); sentence in it, or explicitly declare a static structure and leave it empty. Then re-compile the wrapper of gdal.
If you encounter a similar problem when calling gdal in. Net 4, try this solution.
In fact, not only gdal, but other hosted wrapper made by swig will be affected.
Reference: feiqiu Official Website: http://www.freeeim.com/