• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1---
2layout: default
3title: Plug-ins
4nav_order: 4
5parent: ICU Data
6---
7<!--
8© 2020 and later: Unicode, Inc. and others.
9License & terms of use: http://www.unicode.org/copyright.html
10-->
11
12# Plug-ins
13{: .no_toc }
14
15## Contents
16{: .no_toc .text-delta }
17
181. TOC
19{:toc}
20
21---
22
23## Overview
24
25This page documents the ICU4C DLL Plug-in capability.
26This feature is a Technology Preview which first appeared in ICU4C version
274.3.4. It may be altered or removed in subsequent releases, and feedback is
28appreciated.
29
30## Off by default
31
32As per ticket [ICU-11763](https://unicode-org.atlassian.net/browse/ICU-11763), the plugin
33mechanism discussed here is disabled by default as of ICU 56. Use
34**--enable-plugins** and/or define **UCONFIG_ENABLE_PLUGINS=1** to enable the
35mechanism.
36
37## Background
38
39ICU4C has functionality for registering services, setting
40mutex/allocation handlers, etc. But they must be installed 'before any
41ICU services are used'
42The ICU plugin mechanism allows small code modules, called plugins, to be loaded
43automatically when ICU starts.
44
45## How it works
46
47At u_init time, ICU will read from a list of DLLs and entrypoints, and
48attempt to load plugins found in the list. plugins are called and can
49perform any ICU related function, such as registering or unregistering
50service objects. At u_cleanup time, plugins have the opportunity to
51uninstall themselves before they are removed from memory and unloaded.
52
53## Plugin API
54
55The current plugin API is documented as
56[icuplug.h](https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/icuplug_8h.html)
57Some sample plugins are available at:
58[testplug.c](https://github.com/unicode-org/icu/blob/master/icu4c/source/tools/icuinfo/testplug.c)
59Here is a simple, trivial plugin:
60
61```c
62U_CAPI
63UPlugTokenReturn U_EXPORT2 myPlugin (UPlugData *data, UPlugReason reason, UErrorCode *status) {
64    if(reason==UPLUG_REASON_QUERY) {
65        uplug_setPlugName(data, "Simple Plugin"); /* optional */
66        uplug_setPlugLevel(data, UPLUG_LEVEL_HIGH); /* Mandatory */
67    } else if(reason==UPLUG_REASON_LOAD) {
68        /* ... load ... */
69        /* Set up some ICU things here. */
70    } else if(reason==UPLUG_REASON_UNLOAD) {
71        /* ... unload ... */
72    }
73    return UPLUG_TOKEN; /* Mandatory. */
74}
75```
76
77The `UPlugData*` is an opaque pointer to the plugin-specific data,
78and is used in all other API calls.
79
80The API contract is:
81
821. the plugin MUST always return UPLUG_TOKEN as a return value- to
83indicate that it is a valid plugin.
84
852. when the 'reason' parameter is set to UPLUG_REASON_QUERY, the
86plugin MUST call `uplug_setPlugLevel()` to indicate whether it is a high
87level or low level plugin.
88
893. when the 'reason' parameter is UPLUG_REASON_QUERY, the plugin
90SHOULD call `uplug_setPlugName` to indicate a human readable plugin name.
91
92## Configuration
93
94You can see a sample configuration file here:
95[icuplugins_windows_sample.txt](https://github.com/unicode-org/icu/blob/master/icu4c/source/tools/icuinfo/icuplugins_windows_sample.txt)
96At ICU startup time, the environment variable "ICU_PLUGINS" will be
97queried for a directory name. If it is not set, the #define
98`DEFAULT_ICU_PLUGINS` will be checked for a default value.
99`DEFAULT_ICU_PLUGINS` will be set, on autoconf'ed and installed ICU
100versions, to "$(prefix)/lib/icu" if not set otherwise by the build
101environment.
102Within the above-named directory, the file "icuplugins##.txt" will be
103opened, if present, where _##_ is the major+minor number of the currently
104running ICU (such as, 44 for ICU 4.4).
105So, for example, by default, ICU 4.4 would attempt to open
106`$(prefix)/lib/icu/icuplugins44.txt`
107The configuration file has the following format:
1081. Hash (#) begins a comment line
1092. Non-comment lines have two or three components:
110   > `LIBRARYNAME ENTRYPOINT [ CONFIGURATION .. ]`
1113. Tabs or spaces separate the three items.
1124. _LIBRARYNAME_ is the name of a shared library, either a short name if
113it is on the loader path, or a full pathname.
1145. _ENTRYPOINT_ is the short (undecorated) symbol name of the plugin's
115entrypoint, as above.
1166. _CONFIGURATION_ is the entire rest of the line. It's passed as-is to
117the plugin.
118
119An example configuration file is, in its entirety:
120
121```
122# this is icuplugins44.txt
123testplug.dll myPlugin hello=world
124```
125
126The DLL testplug.dll is opened, and searched for the entrypoint
127"myPlugin", which must meet the API contract above.
128The string "hello=world" is passed to the plugin verbatim.
129
130## Load Order
131
132Plugins are categorized as "high" or "low" level. Low level are those
133which must be run BEFORE high level plugins, and before any operations
134which cause ICU to be 'initialized'. If a plugin is low level but
135causes ICU to allocate memory or become initialized, that plugin is said
136to cause a 'level change'.
137At load time, ICU first queries all plugins to determine their level,
138then loads all 'low' plugins first, and then loads all 'high' plugins.
139Plugins are otherwise loaded in the order listed in the configuration file.
140
141## User interface and troubleshooting
142
143The new command line utility, `icuinfo`, will not only print out ICU
144version information, but will also give information on the load status
145of plugins, with the "-L" option. It will list all loaded or
146possibly-loaded plugins, give their level, and list any errors
147encountered which prevented them from loading. Thus, the end user can
148validate their plugin configuration file to determine if plugins are
149missing, unloadable, or loaded in the wrong order.
150For example the following run shows that the plugin named
151"myPluginFailQuery" did not call `uplug_setPlugLevel()` and thus failed to
152load.
153
154```
155$ icuinfo -v -L
156Compiled against ICU 4.3.4, currently running ICU 4.3.4
157ICUDATA is icudt43l
158plugin file is: /lib/plugins/icuplugins43.txt
159Plugins:
160# Level Name
161Library:Symbol
162config| (configuration string)
163>>> Error | Explanation
164-----------------------------------
165
166#1 HIGH Just a Test High-Level Plugin
167plugin| /lib/plugins/libplugin.dylib:myPlugin
168config| x=4
169
170#2 HIGH High Plugin
171plugin| /lib/plugins/libplugin.dylib:myPluginHigh
172config| x=4
173
174#3 INVALID this plugin did not call uplug_setPlugName()
175plugin| /lib/plugins/libplugin.dylib:myPluginFailQuery
176config| uery
177\\\ status| U_PLUGIN_DIDNT_SET_LEVEL
178/// Error: This plugin did not call uplug_setPlugLevel during QUERY.
179
180#4 LOW Low Plugin
181plugin| /lib/plugins/libplugin.dylib:myPluginLow
182config| x=4
183Default locale is en_US
184Default converter is UTF-8.
185```
186