Apama Documentation : Developing Apama Applications : Developing EPL Plug-ins : EPL Plug-ins in C and C++ Written Prior to 10.0 : Writing a plug-in in C or C++ : A simple plug-in in C++
A simple plug-in in C++
As an example, this topic describes the development of a simple plug-in called, appropriately, simple_plugin. It has only one function, called test, which takes a string as its sole parameter, makes some alterations to it, prints it out, and passes back another string as the result.
Let us first consider a C++ example using the C++ API. The first requirement is to include the header file correlator_plugin.hpp. This header file contains the definitions for the C++ API. The file is located in the Apama installation's include directory.
The C++ method that implements this plug-in function must be defined as follows:
class SimplePlugin {
  public:

  static void AP_PLUGIN_CALL test(
    const AP_Context& ctx,
    const AP_TypeList& args,
    AP_Type& rval,
    AP_TypeDiscriminator rtype);
}
The definition for all plug-in functions must be as for SimplePlugin::test above. In essence only the method name and the enclosing class name should vary as far as the definition is concerned. This is important, since it is the correlator's plug-in support mechanism that will be calling this C++ method and filling in its parameters.
*The ctx parameter is known as the execution context and is used internally by the correlator to make the call to the plug-in function. The developer normally need not be concerned with it in the function's implementation.
*args is an array of parameters; in effect the parameters that the EPL writer will have to supply when calling test.
*rval denotes the return value. Plug-in function implementations must pass out any return value through this parameter, although as will be shown, in EPL the function will appear to return a result in the traditional way. The return value can be a float, boolean, decimal, string, integer or chunk, and the expected return type is indicated by rval.discriminator(). It is not possible to return sequences or other correlator types.
*rtype is the expected return type, identical to the result of calling rval.discriminator() and is retained for backwards compatibility.
The next important step is to define exactly what type of parameters the above plug-in function should expect and accept, what it should return, and under what name it should appear within EPL.
/** Parameter types for the 'test' function */
static const char8* testParamTypes[1] = {"string"};

/** Declare functions provided by this plugin */
static AP_Function Functions[1] = {
  {"test", &SimplePlugin::test, 1, &testParamTypes[0], "string"}
};
The static array of AP_Functions structures needs to be defined in every plug-in to describe which functions that plug-in is exporting to the correlator. In this case the C++ method SimplePlugin::test has been mapped to appear as the external plug-in function "test", to take a single parameter, with the latter being of the EPL type string (as defined within testParamTypes), and return a value of EPL type string. If a particular function returns nothing, the return type should be specified as void.
All that is left is to implement the "C" plug-in initialization method:
AP_PLUGIN_DLL_SYM AP_ErrorCode AP_PLUGIN_CALL
  AP_INIT_FUNCTION_NAME {
    const AP_Context& ctx,
    uint32& version,
    uint32& nFunctions,
    AP_Function*& functions
);
the "C" plug-in shutdown method:
AP_PLUGIN_DLL_SYM AP_ErrorCode AP_PLUGIN_CALL
  AP_SHUTDOWN_FUNCTION_NAME (const AP_Context& ctx);
and the "C" plug-in library version check:
AP_PLUGIN_DLL_SYM AP_ErrorCode AP_PLUGIN_CALL
  AP_LIBRARY_VERSION_FUNCTION_NAME(const AP_Context& ctx,
uint32& version);
The names of the functions are macros defined in correlator_plugin.hpp.
Linking limitations require that these three functions be defined as "C" functions. Both should at least implement the code as indicated in the simple_plugin.cpp example that can be found in the samples\correlator_plugin\cpp directory of your Apama installation. For most situations, it is recommended that the developer re-deploy the initialization and shutdown methods provided unchanged, although more complex plug-ins may include plug-in-specific startup and shutdown code in these functions. Note that the initialization and shutdown functions are invoked each time the library is loaded or unloaded, so these functions must be re-entrant and able to be safely invoked multiple times.
Going back to the implementation of the test method, through use of the extensive library of helper functions available on the AP_Type class, the developer can manipulate the values passed through by the EPL code.
For example, this code displays an integer argument passed to a function:
cout << args[0].integerValue();
while this call increments the second element of a sequence argument:
AP_Type &element = args[0][2];
element.integerValue(element.integerValue()+1);
Note that this is relevant since sequences and chunks are passed by reference. So, if the EPL code calling it was:
sequence<integer> mySeq := [0,10,20,30];
myPlugin.exampleFunction(mySeq);
print mySeq;
then after the call mySeq is [0,10,21,30].
Note that this is modifying the sequence to which mySeq refers, not altering the value of mySeq itself. A plug-in function cannot do the equivalent of mySeq := otherSeq;.
Similarly, it is not possible to modify primitives passed to a plug-in as arguments. Strings, while strictly speaking a reference type, are immutable and so cannot be modified either.
The complete code base of this simple example can be found in the simple_plugin.cpp file which is located in the samples\correlator_plugin\cpp\ directory of your Apama installation. A makefile (for use with GNU Make) and a batch file (for Microsoft's Visual Studio) are provided in this directory to assist with compiling plug-ins on UNIX and Windows platforms respectively. A README.txt file in the directory describes how to build the example.
Copyright © 2013-2017 Software AG, Darmstadt, Germany. (Innovation Release)

Product LogoContact Support   |   Community   |   Feedback