MS RFC 8:可插拔外部特性层提供程序

日期

2005/10/26

作者

贾尼阿维巴赫

联系方式

javerbach在extendtherach.com上

状态

采用

版本

MAPServer 4.8

目的

本建议的目的是为用户提供一种在运行时向mapserver提供插件外部第三方功能层的方法。

抽象解

提供一种方法,让用户通过 Mapfile 知道要为层加载哪个库,然后根据需要加载此库并将其缓存以供以后使用,然后通过层的虚拟表将其绑定到正在运行的MapServer。

技术解决方案

  • 新的 CONFIG 选项 MS_PLUGIN_DIR 如果设置了,它将告诉插件的基本路径

  • 新建 Mapfile 关键字 PLUGIN 带字符串参数。这个关键字告诉为这个层动态加载哪个库。

    插件的加载基于以下算法:

    • 如果缺少插件字符串 .so.dll 扩展名,将其附加到插件字符串

    • 如果 MS_PLUGIN_DIR 已设置,插件字符串不是绝对路径,插件字符串的前缀为 MS_PLUGIN_DIR

    • 否则直接使用插件字符串

    通常,如果路径不是绝对路径,动态库加载程序将使用系统路径来查找要加载的适当插件。

  • 新建连接类型 PLUGIN

  • 新领域 char* plugin_library 在layerobj结构中,这是要为此层加载的库的名称。

  • 函数获取请求层的虚拟表。如果库尚未加载,则将按需加载。

    static const layerVTableObj *
    getCustomLayerVirtualTable(layerObj *layer)
    

    在哪里? layerVTableObj 是虚拟表,层是自定义层。如果出现错误,函数将返回 NULL .

  • 函数从动态加载库中获取函数指针。此函数还将加载库。

    msGetDynamicLibrarySymbol(const char *Library,
                              const char *SymbolName)
    

    这是由gdal项目实现的,我计划使用它们的实现( CPLGetSymbol

  • 已加载库的缓存结构。此缓存结构将由库的全名/路径(由用户通过mapfile提供)和指向虚拟表初始化函数的函数指针组成。缓存的大小将是固定的,并且将与最大层数相同(目前为200层)。这是可以同时加载的MapServer的最大不同自定义层数。这个缓存实现是内部的,所以如果必须动态分配,以后可以在不破坏接口的情况下执行。

  • 新锁定项( TLOCK_LAYER_VTABLE )保护库缓存结构。

受影响的文件和对象

此建议将至少影响以下文件和对象:

  • map.h

    • layerObj 将包含一个新字段, char *plugin_library .

  • 新的锁令牌 TLOCK_LAYER_VTABLE

  • 用于自定义层处理的新文件和对象。

向后兼容性问题

此更改是二进制不兼容的,但 Mapfile 向后兼容。它将添加一个旧映射服务器未知的新关键字。

实施问题

没有

臭虫识别码

错误 1477

投票历史

Jani Averbach于2005年10月26日提出投票,初始结果为+3,修正后的RFC得到+4(3名无投票权成员)。

投票+1:Frank Warmerdam、Steve Lime、Yewondwossen Assefa、Daniel Morissette

提案通过并将继续推进。

开放性问题

没有

工作笔记

插件库必须实现函数 PluginInitializeVirtualTable

int (*pfnPluginInitVTable)(layerVTableObj *,
                           layerObj *);

在库加载期间调用。此函数负责填充 layerVTableObj * 虚拟表。如果此函数留下一些函数指针指向 NULL 在这个虚拟表中,默认操作用于这些缺少的函数。默认值在函数中可见 maplayer.c: populateVirtualTable(...) . 函数不能直接填充 layerObj->vtable ,必须使用 layerVTableObj * 对此的论证。地图服务器正在等待 TLOCK_LAYER_VTABLE 在此函数调用期间锁定。