.NET MapScript编译

作者

塔玛斯塞克勒斯

联系

gmail.com上的szekerest

汇编

在编译C mapscript之前,您应该使用满足您需求的选项来编译mapserver。有关编译mapserver的详细信息,请参阅 Win32 Compilation and Installation Guide . 强烈建议尽量减少应用程序的库依赖性,因此在编译MapServer时,只启用真正需要的功能。要编译C绑定swig 1.3.31或更高版本是必需的。

警告

此文档可能引用旧的库版本。您可能希望尝试为生成使用更新的库版本。

针对MS.NET Framework 1.1的Win32编译

应该使用Visual Studio 2003编译MapServer、MapScript和所有后续库。下载并解压缩包含预编译Swig.exe的最新Swigwin包,打开Visual Studio.NET 2003命令提示符,进入/mapscript/csharp目录。编辑makefile.vc并将swig变量设置为swig.exe的位置

用途:

nmake -f makefile.vc

编译mapscript.dll和mapscript_csharp.dll。

针对MS.NET Framework 2.0的Win32编译

应该使用Visual Studio 2005编译MapServer、MapScript和所有后续库。下载并解压缩包含预编译swig.exe的最新swigwin包,打开Visual Studio 2005命令提示符,进入/mapscript/csharp目录edit makefile.vc并将swig变量设置为swig.exe的位置。

用途:

nmake -f makefile.vc

编译mapscript.dll和mapscript_csharp.dll。

针对Mono框架的Win32编译

在编译之前,您应该下载并安装最新的Mono Win32安装程序包(例如Mono-1.1.13.2-gtksharp-2.8.1-win32-1.exe),编辑makefile.vc并将csc变量设置为mcs.exe的位置。或者,您可以定义:

MONO = YES

在nmake.opt文件中。

编译mapscript时应使用与编译mapserver时相同的编译器。要编译mapscript,请打开编译器提供的命令提示符,并使用:

nmake -f makefile.vc

编译mapscript.dll和mapscript_csharp.dll。

Windows上的可选编译方法

从MapServer 4.8.3开始,可以通过在nmake.opt:中取消对dot_net的注释,从MapServer目录调用C_编译:

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# .NET/C# MapScript
# ----------------------------------------------------------------------
# .NET will of course only work with MSVC 7.0 and 7.1.  Also note that
# you will definitely want USE_THREAD defined.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#DOT_NET = YES

并通过以下方式调用编译:

nmake -f makefile.vc csharp

您还可以使用:

nmake -f makefile.vc install

使编译成为将目标复制到公共输出目录中。

测试编译

对于测试编译和运行时环境,可以使用:

nmake -f makefile.vc test

在csharp目录中启动以前编译的示例应用程序。在进行测试之前,相应库的位置应该包括在系统路径中。

针对Mono框架的Linux编译

在编译之前,您应该下载并安装最新的Mono Linux包。有些发行版有要安装的预编译二进制文件,但是为了使用最新版本,您可能需要从源代码处编译并安装它。下载并解压缩最新的swig版本。如果您的平台没有预编译的二进制文件,那么您可能应该从源代码编译它。

在编译mapscript之前,应该配置和编译mapserver。从MapServer 4.8.2开始,在配置期间,将根据配置选项创建mapscript/csharp/makefile。如果默认情况下无法访问文件,请编辑此文件并为相应的可执行路径设置swig和csc。要在控制台步骤中编译到/mapscript/csharp目录,请使用:

make

编译libmapscript.so和mapscript_csharp.dll。

对于测试编译和运行时环境,可以使用:

make test

用于启动以前编译的示例应用程序。

面向Mono框架的OSX编译

从4.10.0开始,csharp/makefile支持OSX构建。在进行构建之前,应在系统上安装最新的单声道软件包。

在编译mapscript之前,应该配置和编译mapserver。从MapServer 4.8.2开始,在配置期间,将根据配置选项创建mapscript/csharp/makefile。如果默认情况下无法访问文件,请编辑此文件并为相应的可执行路径设置swig和csc。要在控制台步骤中编译到/mapscript/csharp目录,请使用:

make

编译libmapscript.dylib和mapscript_csharp.dll。

对于测试编译和运行时环境,可以使用:

make test

用于启动以前编译的示例应用程序。

要运行应用程序,需要将mapscript_csharp.dll.config与mapscript_csharp.dll文件一起使用。此文件是在生成过程中创建的

安装

应用程序所需的文件应手动安装。强烈建议将文件复制到可执行文件所在的文件夹中。

已知问题

Visual Studio 2005需要清单文件才能加载CRT本机程序集包装

如果已经编译了用于使用CRT库的MapServer,并且正在使用MS.NET Framework 2.0作为执行运行时,则应随可执行文件一起提供适当的清单文件,例如:

<?xml version="1.0" encoding="utf-8"?>
<assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1
 assembly.adaptive.xsd" manifestVersion="1.0"
 xmlns:asmv1="urn:schemas-microsoft-com:asm.v1"
 xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"
 xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"
 xmlns="urn:schemas-microsoft-com:asm.v1"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<assemblyIdentity name="drawmap.exe" version="1.0.0.0" type="win32" />
<dependency>
<dependentAssembly asmv2:dependencyType="install"
 asmv2:codebase="Microsoft.VC80.CRT.manifest" asmv2:size="522">
<assemblyIdentity name="Microsoft.VC80.CRT" version="8.0.50608.0"
 publicKeyToken="1fc8b3b9a1e18e3b" processorArchitecture="x86"
 type="win32" />
<hash xmlns="urn:schemas-microsoft-com:asm.v2">
<dsig:Transforms>
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<dsig:DigestValue>UMOlhUBGeKRrrg9DaaPNgyhRjyM=</dsig:DigestValue>
</hash>
</dependentAssembly>
</dependency>
</assembly>

这将通知clr您的exe依赖于crt,并且要使用正确的程序集包装器。如果使用的是IDE,则可以通过在/microsoft Visual Studio 8/vc/redist/x86/microsoft.vc80.crt.crt目录中添加对microsoft.vc80.crt.manifest的引用来预生成清单文件。

必须将dll-s的清单嵌入为资源

根据Windows Makefile,mapscript编译目标(mapscript.dll)与/md选项链接。在这种情况下,VS2005链接器将生成包含非托管程序集依赖项的清单文件。清单文件的示例内容为:

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<dependency>
<dependentAssembly>
<assemblyIdentity type='win32' name='Microsoft.VC80.CRT'
 version='8.0.50608.0' processorArchitecture='x86'
 publicKeyToken='1fc8b3b9a1e18e3b' />
</dependentAssembly>
</dependency>
</assembly>

如前所述,如果要创建Windows应用程序,公共语言运行库将搜索应用程序的清单文件。清单文件的名称应与可执行文件append相同,并以.manifest扩展名结尾。但是,如果主机进程不受您的控制(如使用aspnet_wp.exe作为主机进程的Web映射应用程序),您将无法确定主机进程(.exe)是否具有包含对CRT包装器引用的清单。在这种情况下,您可能需要使用mt工具将清单作为资源嵌入到dll中,例如:

mt /manifest mapscript.dll.manifest /outputresource:mapscript.dll;#2

公共语言运行库将搜索嵌入的资源并正确加载CRT程序集。

通常,用根dll(mapscript.dll)加载crt已经足够了,但是将清单嵌入到依赖库中也没有什么害处。

与Regex和Visual Studio 2005一起发布

使用Microsoft Visual Studio 2005编译时,regex.c和crtdefs.h之间可能会发生变量名冲突。有关详细信息,请参见:

https://github.com/MapServer/MapServer/issues/1651

C使用Mono的mapscript库名称映射

使用由swig接口生成器创建的mapscript接口,C包装类(mapscript _csharp.dll)和C代码(mapscript.dll)之间的通信使用如下平台调用进行:

[DllImport("mapscript", EntryPoint="CSharp_new_mapObj")]
public static extern IntPtr new_mapObj(string jarg1);

dllimport声明包含库名称,但是要将库名称转换为文件名,需要依赖于平台。在Windows上,库名只需附加.dll扩展名(mapscript.dll)。在UNIX系统上,库文件名通常以lib前缀开头,并附加.so扩展名(libmapscript.so)。

可以使用dll.config文件手动控制库名称的映射。这只需将dllimport要查找的库文件映射到其unix等效文件。文件通常包含以下信息(mapscript_csharp.dll.config)::

<configuration>
  <dllmap dll="mapscript" target="libmapscript.so" />
</configuration>

使用OSX构建:

<configuration>
  <dllmap dll="mapscript" target="libmapscript.dylib" />
</configuration>

该文件应与相应的mapscript_csharp.dll文件一起放置,并在生成过程中默认创建。有关详细信息,请参阅:

https://github.com/MapServer/MapServer/issues/1596 http://www.mono-project.com/Interop_with_Native_Libraries

Mono/Linux的本地化问题

根据https://github.com/MapServer/MapServer/issues/1762的说法,地图服务器可能不会在不同的地区设置上运行得同样好。尤其是当小数分隔符不是“.”时。当映射文件包含浮点数时,进程区域设置内部可能会导致解析错误。由于mono进程接管了环境的区域设置,因此值得考虑将主机进程的默认区域设置设置为“C”,例如:

LC_ALL=C mono ./drawmap.exe ../../tests/test.map test_csharp.png

最常见的错误

本章将总结用户可能遇到的最常见问题。这些问题主要是从-用户列表和IRC收集的。

无法加载dll(mapscript)

您可以在Windows上得到这个问题,在大多数情况下,它可以专用于丢失或不可加载的共享库。错误消息讨论了mapscript.dll,但libmap.dll所依赖的一个或多个dll-s肯定丢失了。因此,首先,您可能需要检查应用程序目录中libmap.dll的依赖项。您可以使用Visual Studio依赖关系查看器来完成此任务。您还可以使用文件监视工具(如sysinternal的filemon)检测无法加载的dll-s。我建议将应用程序所需的所有DLL-S存储在应用程序文件夹中。如果可以使用映射文件运行drawmap c示例应用程序,则编译可能是正确的,并且所有DLL都可用。

您可能会发现对于桌面和ASP.NET应用程序,mapscript c接口的行为不同。虽然可以正确运行drawmap示例,但ASP.NET应用程序可能会遇到dll加载问题。创建ASP.NET项目时,默认情况下,应用程序文件夹为“inetpubwwwroot[yourapp]bin”。根据您的系统,应用程序的主机进程将是aspnet_wp.exe或w3wp.exe。应用程序将在与交互用户不同的安全上下文下运行(默认情况下,在aspnet用户上下文下)。当将dll-s放在应用程序目录之外时,您应该考虑到path环境变量在interactive和aspnet用户之间可能有所不同,并且/或者您可能没有足够的权限访问应用程序文件夹之外的dll。

错误报告

如果您发现专门针对MapScrip C#接口的问题,请随时将错误报告提交到 Issue Tracker