Plug-in API
On this page:
The Plugin Interface
The plug-in facility defines a local Slice interface that all plug-ins must implement:
module Ice
{
local interface Plugin
{
void initialize();
void destroy();
}
}
The lifecycle of an Ice plug-in is structured to accommodate dependencies between plug-ins, such as when a logger plug-in needs to use IceSSL for its logging activities. Consequently, a plug-in object's lifecycle consists of four phases:
- Construction
The Ice run time uses a language-specific factory API for instantiating plug-ins. During construction, a plug-in can acquire resources but must not spawn new threads or perform activities that depend on other plug-ins.
- Initialization
After all plug-ins have been constructed, the Ice run time invokesinitializeon each plug-in. The order in which plug-ins are initialized is undefined by default but can be customized using a configuration property. If a plug-in has a dependency on another plug-in, you must configure the Ice run time so that initialization occurs in the proper order. In this phase it is safe for a plug-in to spawn new threads; it is also safe for a plug-in to interact with other plug-ins and use their services, as long as those plug-ins have already been initialized. Ifinitializeraises an exception, the Ice run time invokesdestroyon all plug-ins that were successfully initialized (in the reverse order of initialization) and raises the original exception to the application.
- Active
The active phase spans the time between initialization and destruction. Plug-ins must be designed to operate safely in the context of multiple threads.
Destruction
The Ice run time invokesdestroyon each plug-in in the reverse order of initialization.A plug-in's
destroyimplementation must not make remote invocations.
This lifecycle is repeated for each new communicator that an application creates and destroys.
C++ Plug-in Factory
In C++, a plug-in factory is a function with C linkage and the following signature:
extern "C"
{
Ice::Plugin* functionName(const std::shared_ptr<Ice::Communicator>& communicator,
const std::string& name,
const Ice::StringSeq& args)
{
...
}
}
extern "C"
{
Ice::Plugin* functionName(const Ice::CommunicatorPtr& communicator,
const std::string& name,
const Ice::StringSeq& args)
{
...
}
}
You can choose any name for the factory function.
Since the function uses C linkage, it must return the plug-in object as a regular C++ pointer and not as a smart pointer. Furthermore, the function must not raise C++ exceptions; if an error occurs, the function must return zero. The arguments to the function consist of the communicator that is in the process of being initialized, the name assigned to the plug-in, and any arguments that were specified in the plug-in's configuration.
If your plug-in and the associated factory function are packaged in a shared library or DLL loaded at run time, you need to export this function from the shared library or DLL. We provide the macro ICE_DECLSPEC_EXPORT for this purpose:
#if defined(_MSC_VER)
# define ICE_DECLSPEC_EXPORT __declspec(dllexport)
...
#elif defined(__GNUC__) || defined(__clang__)
# define ICE_DECLSPEC_EXPORT __attribute__((visibility ("default")))
...
Simply add ICE_DECLSPEC_EXPORT to the definition of your plug-in factory:
extern "C"
{
ICE_DECLSPEC_EXPORT Ice::Plugin* functionName(const std::shared_ptr<Ice::Communicator>& communicator,
const std::string& name,
const Ice::StringSeq& args)
{
...
}
}
extern "C"
{
ICE_DECLSPEC_EXPORT Ice::Plugin* functionName(const Ice::CommunicatorPtr& communicator,
const std::string& name,
const Ice::StringSeq& args)
{
...
}
}
If you don't want to rely on the dynamic loading of your plug-in shared library or DLL at run time, or if your plug-in is packaged in a static library, you can also link the plug-in into your application and call Ice::registerPluginFactory in your main application's code to register the plug-in before you initialize Ice communicators. For example:
MyApp::MyApp()
{
// Load/link the "IceSSL" plug-in before communicator initialization
Ice::registerPluginFactory("IceSSL", createIceSSL, false);
}
The registerPluginFactory function registers the plug-in's factory function with the Ice run time. It returns void, and accepts the following parameters:
const string&
The name of the plug-in.PLUGIN_FACTORY
A pointer to the plug-in factory function.bool
Whentrue, the plug-in is always loaded (created) during communicator initialization, even ifIce.Plugin.nameis not set. Whenfalse, the plug-in is loaded (created) during communication initialization only ifIce.Plugin.nameis set to a non-empty value (e.g.:Ice.Plugin.IceSSL=1).
Java Plug-in Factory
In Java, a plug-in factory must implement the PluginFactory interface:
package com.zeroc.Ice;
public interface PluginFactory
{
Plugin create(Communicator communicator, String name, String[] args);
}
package Ice;
public interface PluginFactory
{
Plugin create(Communicator communicator, String name, String[] args);
}
The arguments to the create method consist of the communicator that is in the process of being initialized, the name assigned to the plug-in, and any arguments that were specified in the plug-in's configuration.
The create method can return null to indicate that a general error occurred, or it can raise PluginInitializationException to provide more detailed information. If any other exception is raised, the Ice run time wraps it inside an instance of PluginInitializationException.
C# Plug-in Factory
In .NET, a plug-in factory must implement the Ice.PluginFactory interface:
namespace Ice
{
public interface PluginFactory
{
Plugin create(Communicator communicator, string name, string[] args);
}
}
The arguments to the create method consist of the communicator that is in the process of being initialized, the name assigned to the plug-in, and any arguments that were specified in the plug-in's configuration.
The create method can return null to indicate that a general error occurred, or it can raise PluginInitializationException to provide more detailed information. If any other exception is raised, the Ice run time wraps it inside an instance of PluginInitializationException.