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

日期

2005/10/26

作者

贾尼阿维巴赫

联系

javerbach在extendtherach.com上

状态

采用

版本

MAPServer 4.8

目的

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

抽象解

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

技术解决方案

  • 新的 CONFIG 选项 MS_PLUGIN_DIR 如果设置,则告知插件的基本路径

  • 新的映射文件关键字 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

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

向后兼容性问题

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

实施问题

没有

臭虫识别码

臭虫1477

投票历史

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

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

提案通过并将继续推进。

开放性问题

没有

工作笔记

插件库必须实现功能 PluginInitializeVirtualTable

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

which is called during library loading. This function is responsible to populate layerVTableObj * virtual table. If this function leaves some function pointers to NULL in this virtual table, then default actions are used for these missing functions. The defaults are visible in function maplayer.c: populateVirtualTable(...). The function must not populate directly layerObj->vtable, it have to use layerVTableObj * argument for this. The MapServer is holding TLOCK_LAYER_VTABLE lock during this function call.