Apama 10.7.2 | Developing Apama Applications | Developing EPL Plug-ins | Writing EPL Plug-ins in C++ | Creating a plug-in using C++
 
Creating a plug-in using C++
 
Method signatures
Compiling C++ plug-ins
Exceptions
Writing to the correlator log file
Storing data using chunks
Sending events
Receiving events
Blocking behavior of plug-ins
Load-time or unload-time code
Handling thread-specific data in plug-ins
The APIs for writing plug-ins in C++ are all documented in the API Reference for C++ (Doxygen). The relevant classes are in the com::apama::epl:: namespace, provided in the epl_plugin.hpp header file.
To create a plug-in for EPL in C++, you have to create a class which inherits from EPLPlugin. EPLPlugin is a class template with one template parameter, which should be the derived class which implements your plug-in. Your class must provide a zero-argument constructor and a static initialize method which takes a base_plugin_t::method_data_t & argument. For example:
class MyPlugin: public EPLPlugin<MyPlugin>
{
public:
MyPlugin(): base_plugin_t("MyPlugin")
{}
static void initialize(base_plugin_t::method_data_t &md)
{
}
};
base_plugin_t is a convenience typedef to the EPLPlugin base class. The base class constructor takes a single argument of descriptive string which is used for logging purposes. The base class provides two members to derived classes:
Member
Description
logger
A Logger object which can be used to write to the correlator log file. See also Writing to the correlator log file.
static getCorrelator()
Returns a CorrelatorInterface & which can be used to make various callbacks into the correlator.
A single instance of your class is created when the plug-in is loaded. Functions which you want to expose to EPL are member functions on that instance. To export a function to EPL, you need to declare a member function on the class with argument and return types which can be translated into EPL (see Method signatures). The function is exported into EPL by calling registerMethod on the method_data_t passed to initialize:
static void initialize(base_plugin_t::method_data_t &md)
{
md.registerMethod<decltype(&MyPlugin::doSomething),
&MyPlugin::doSomething>("doSomething");
}
void doSomething(int64_t arg1, double arg2)
{
// ...
}
registerMethod is templated over the following:
*the type of the function to export, which can be shortcut with decltype() as shown above, and
*the function to export.
registerMethod takes a mandatory argument, which is the name of the function in EPL, and two optional arguments.
*If the method signatures in EPL are not deducible from the C++ arguments, then you must provide the EPL type signature of the method.
*There is a final Boolean parameter, which defaults to true. It should be true if the plug-in may block (see Blocking behavior of plug-ins) and false otherwise.
md.registerMethod<decltype(&MyPlugin::simpleSignature),
&MyPlugin::simpleSignature>("simpleMethod");
md.registerMethod<decltype(&MyPlugin::simpleSignatureNonBlocking),
&MyPlugin::simpleSignatureNonBlocking>("nonBlockingMethod", false);
md.registerMethod<decltype(&MyPlugin::complexSignature),
&MyPlugin::complexSignature>("complexMethod",
"action<sequence<string>, integer> returns string");
Finally, to export the plug-in, you have to use the APAMA_DECLARE_EPL_PLUGIN macro. If your class is in a namespace, then you have to put the macro inside the same namespace and give it the class name without qualification as an argument:
APAMA_DECLARE_EPL_PLUGIN(MyClass)
Plug-ins are loaded into the correlator by using the import statement in the monitor or event which wants to use the plug-in. The argument is the name of the library which contains the plug-in.
import "MyPlugin" as plugin;
Complete simple example
This example implements a plug-in which simply keeps a single global count.
#include <epl_plugin.hpp>
using namespace com::apama::epl;

class CountPlugin: public EPLPlugin<MyPlugin>
{
public:
CountPlugin()
: base_plugin_t("CountPlugin"),
count(0)
{}
static void initialize(base_plugin_t::method_data_t &md)
{
md.registerMethod<decltype(&CountPlugin::incrementCount),
&CountPlugin::incrementCount>("increment");
md.registerMethod<decltype(&CountPlugin::getCount),
&CountPlugin::getCount>("getCount");
}
int64_t getCount() { return count; }
void incrementCount(int64_t n) { count += n; }
// Note that this is not thread-safe; a real plug-in would
// want to use some synchronization here
private:
int64_t count;
};
 
monitor foo
{
import "PluginLibrary" as counter;
action onload()
{
on all A() {
counter.increment(1);
print "Current count: "+counter.getCount().toString();
}
}
}