Function models for C++ native functions
To create a function model, you create
a function.xml file that is structured as
a sequence of one or more functionSet
elements.
The functionSet
element from the
schema for the function.xml represents the set
of native functions declared within or included from a C++ header
file. It contains three subelements. The first one is the headerFileName
element,
which contains the name of the header file that declares the
C++ functions or includes other header files that declare them.
The second (optional) element is named cppNamespacename
,
which gives the C++ namespace for the functions. If the cppNamespacename
element
is not present, the SPL namespace, with ".
" converted
to "::
" is used. The third element is named functions
,
which contains a sequence of one or more function
elements,
each representing a native function signature in SPL format. An optional cppName
attribute
specifies the C++ name of the function. If not present, the SPL function
name is used. The fourth element is an optional one, named dependenciesType
.
It is a sequence of one or more library
elements,
each representing a library dependency. The library
element
format is the same as the one used for operator models. Library dependencies
specify the include directories, library paths, and library names
that are required to compile and link SPL applications to use the
functions that are listed in the function set.
<functionModel
xmlns="http://www.ibm.com/xmlns/prod/streams/spl/function"
xmlns:cmn="http://www.ibm.com/xmlns/prod/streams/spl/common"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ibm.com/xmlns/prod/streams/spl/function functionModel.xsd">
<functionSet>
<!-- header file to include from within C++ code -->
<headerFileName>Sample.h</headerFileName>
<!-- functions lists the SPL prototypes of the functions implemented in this library -->
<functions>
<!-- use of CDATA allows easy use of < in the prototypyes -->
<function>
<description>Increment all list elements by a given amount</description>
<prototype cppName="increment_by"><![CDATA[ void incrementBy(mutable list<int32> l,
int32 incr) ]]></prototype>
</function>
<function>
<description>Join two lists</description>
<prototype><![CDATA[ list<int32> joinLists(list<int32> a, list<int32> b) ]]></prototype>
</function>
</functions>
<dependencies>
<!-- This library can have several dependencies. We only use one here -->
<library>
<!-- A description for this library -->
<cmn:description>Sample-Functions</cmn:description>
<cmn:managedLibrary>
<!-- the name of the library for linking. Will be used as -lSample -->
<cmn:lib>Sample</cmn:lib>
<!-- Where to find the library. Relative to the current directory.
Will be used as -L<dir>/lib -->
<cmn:libPath>lib</cmn:libPath>
<!-- Where to find the include file. Relative to the current directory.
Will be used as -I<dir> -->
<cmn:includePath>./</cmn:includePath>
</cmn:managedLibrary>
</library>
</dependencies>
</functionSet>
</functionModel>
The cppName
attribute
on routine incrementBy
allows the SPL program to
call routine incrementBy
, but invokes the C++ routine increment_by
,
which must be declared in Sample.h
. Use of cppName
allows
SPL programs to invoke C++ routines that might conflict with SPL keywords,
or contain characters such as $
that are not allowed
in most SPL identifiers.
The C++ header file that is needed
for using the functions that are listed is named Sample.h
.
The native functions that are included in this function model file
are implemented in a library that is described as Sample-Functions
.
The header files are in the directory ./,
which is relative to the location of the function.xml file.
The library path for the C++ library that implements the functions
are in the ./lib directory, again relative to
the directory that contains the function model file. Finally,
the name of the C++ library name is Sample
, which
means that the library file is named as either libSample.so (dynamic)
or libSample.a (static). The directory structure
for this sample is:
/+ function.xml
/+ Sample.h
/+ lib
/+ libSample.so
cmn:command
element can be used
to pick the right one to use at compilation time. The following is
such an example:<library>
<cmn:description>Sample-Functions</cmn:description>
<cmn:managedLibrary>
<cmn:libPath>lib</cmn:libPath>
<cmn:includePath>./</cmn:includePath>
<cmn:command>get-lib-conf</cmn:command>
</cmn:managedLibrary>
</library>
/+ function.xml
/+ get-lib-conf
/+ Sample.h
/+ lib-x86_64
/+ libSample.so
/+ lib-ppc64
/+ libSample.so
#!/bin/bash
if [ "$1" == "libPath" ]; then
arch=$(uname -m)
if [ $arch == "x86_64" ]; then
echo "./lib-x86_64"
elif [ $arch == "ppc64" ]; then
echo "./lib-ppc64"
else
echo "Unsupported platform $arch" >&2
exit 1;
fi
fi