Home » Eclipse Projects » Eclipse Titan » Embedding Python in TTCN-3 with Eclipse Titan - External functions(Embedding Python code in TTCN-3 with Eclipse Titan as external function)
Embedding Python in TTCN-3 with Eclipse Titan - External functions [message #1703268] |
Thu, 30 July 2015 06:37 |
|
As we have established earlier, Titan can talk directly to C/C++; this can be used as a bridge to reach other language environments, Python for instance.
Python also has a well-documented C API, see ref.1.
What such a connection could be used for? For instance , the following:
-Quick prototyping of an external function to be eventually written in C/C++
-Calling functions from existing Python libraries,
e.g. cryptography, scientific libraries, FastFourierTransform, compression etc.
-Configuration preambles, where message analysis is not relevant
-Integrating Python frameworks into Titan
Let's see a concrete example.
Python_Compression.ttcn contains external function calls to compression functions:
module Python_Compression
{
external function f_compress(charstring pl_string) return octetstring;
external function f_uncompress(octetstring pl_string) return charstring;
control
{
var charstring v_before:= "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
var octetstring v_compressed := f_compress(v_before);
var charstring v_after:=f_uncompress(v_compressed);
log("Compressed: ",v_compressed," Compresssed length: ", lengthof(v_compressed));
log("Uncompresssed ",v_after, " Uncompressed length: ", lengthof(v_after));
log("Uncompressed octetstring ",
f_uncompress('789C3590CB7103310C435B41019EAD22B9E59A021809EB70463F4BA4C7E587CA2637512441E07DF4C90A1DCB2B722F7D62A9412AED86D4DB62329A4F48D6A14B93B63B5834BA8B393640F5557B86B18ED8D696346BF666704391AFD007EDD226AADC9B408A3E5C0E7C1AD8B48638AAEEC7334AA9373C5C175A5F363D832FCEA426A6BDC14B919AFAA5BC87C2D4BEF42BA923864109E7353CF52B419CB2036F5B52DC089D1E4EAEB0DA303926BFD93267248F8F672F3EE21CC34E2405D7229296F28F2802394EBFAB18DA368421330A9F07DE5F89C3E89B6330E8290953CC251F9AC5F646A418B36B66DB1437A9389ABC0CD9B9D1CF33300B3217E7EED65EB60DD9803470AC3FAE5E8F1F55D5A572'O));
}//endcontrol
}//endmodule
The function definitions are contained in Compress.cc:
#include <Python.h> /* standard API def */
#include "Python_Compression.hh"
namespace Python__Compression
{
OCTETSTRING f__compress(const CHARSTRING& pl__string) {
int cstrLen = strlen(pl__string);
const char *cstr = pl__string;;
PyObject *pstr, *pmod, *pfunc, *pargs;
/* Initialize the Python Interpreter */
Py_Initialize();
PyRun_SimpleString("import sys");
/* export PYTHONPATH=. */
PyRun_SimpleString("sys.path.append('.')");
/* import module compression */
pmod = PyImport_ImportModule("compression");
/* call compression.compress() */
pfunc = PyObject_GetAttrString(pmod, "compress");
pargs = Py_BuildValue("(s)", cstr);
pstr = PyEval_CallObject(pfunc, pargs);
PyArg_Parse(pstr, "s#", &cstr,&cstrLen);
OCTETSTRING ret_val(cstrLen, (const unsigned char *)cstr);
/* free owned objects */
Py_DECREF(pmod);
Py_DECREF(pstr);
Py_DECREF(pfunc); /* not really needed here */
Py_DECREF(pargs); /* since all memory goes away */
/* Finish the Python Interpreter */
Py_Finalize();
return ret_val;
}
CHARSTRING f__uncompress(const OCTETSTRING& pl__string) {
PyObject *pstr, *pmod, *pfunc, *pargs;
/* Initialize the Python Interpreter */
Py_Initialize();
PyRun_SimpleString("import sys");
/* export PYTHONPATH=. */
PyRun_SimpleString("sys.path.append('.')");
int cstrLen = pl__string.lengthof();
const unsigned char *ostr = pl__string;
const char *cstr = (const char *)ostr;
/* import module compression */
pmod = PyImport_ImportModule("compression");
/* call compression.decompress() */
pfunc = PyObject_GetAttrString(pmod, "decompress");
pargs = Py_BuildValue("(s#)", cstr,cstrLen);
pstr = PyEval_CallObject(pfunc, pargs);
if (! PyArg_Parse(pstr, "s", &cstr)) return "";
CHARSTRING ret_val(cstr);
/* free owned objects */
Py_DECREF(pmod);
Py_DECREF(pstr);
Py_DECREF(pfunc); /* not really needed here */
Py_DECREF(pargs); /* since all memory goes away */
/* Finish the Python Interpreter */
Py_Finalize();
return ret_val;
}
}
The C code initializes the Python environment and executes the compression/decompression in it.
The referred Python functions are defined in compression.py:
"""
#############################################################
ZLIB based compression
#############################################################
"""
import zlib
def compress(input):
binary = zlib.compress(input)
return binary
def decompress(input):
string = zlib.decompress(input)
return string
The Makefile was generated with:
makefilegen -s -e Compress *.ttcn *.cc
Of course, the Python libraries are to be added to the build(see Makefile) :
# Flags for the C++ preprocessor (and makedepend as well):
CPPFLAGS = -D$(PLATFORM) -I$(TTCN3_DIR)/include -I/usr/include/python2.6
:
:
:
LINUX_LIBS = -lxml2 -lpython2.6
After running the executable:
the result can be observed in the generated log file:
11:01:10.667642 Python_Compression.ttcn:9 Execution of control part in module Python_Compression started.
11:01:10.690932 Python_Compression.ttcn:18 Compressed: '789C3590CB7103310C435B41019EAD22B9E59A021809EB70463F4BA4C7E587CA2637512441E07DF4C90A1DCB2B722F7D62A9412AED86D4DB62329A4F48D6A14B93B63B5834BA8B393640F5557B86B18ED8D696346BF666704391AFD007EDD226AADC9B408A3E5C0E7C1AD8B48638AAEEC7334AA9373C5C175A5F363D832FCEA426A6BDC14B919AFAA5BC87C2D4BEF42BA923864109E7353CF52B419CB2036F5B52DC089D1E4EAEB0DA303926BFD93267248F8F672F3EE21CC34E2405D7229296F28F2802394EBFAB18DA368421330A9F07DE5F89C3E89B6330E8290953CC251F9AC5F646A418B36B66DB1437A9389ABC0CD9B9D1CF33300B3217E7EED65EB60DD9803470AC3FAE5E8F1F55D5A572'O Compresssed length: 270
11:01:10.691265 Python_Compression.ttcn:20 Uncompresssed "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." Uncompressed length: 446
11:01:10.691329 Python_Compression.ttcn:21 Uncompressed octetstring "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
11:01:10.700345 Python_Compression.ttcn:21 Execution of control part in module Python_Compression finished.
References:
Ref.1 Python/C API Reference Manual http://docs.python.org/2/c-api/
Ref.2 Mark Lutz: Programming Python 4th Edition, Chapter 20: Python/C Integration
The same trick can be used with Java (JNI), Ruby , or any other language implementation that has a well-defined C API.
Best regards
Elemer
|
|
|
Goto Forum:
Current Time: Thu Apr 25 09:51:17 GMT 2024
Powered by FUDForum. Page generated in 0.03009 seconds
|