Using Python as an
Extension Language

Rick Ratzel

rlratzel@users.sourceforge.net

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

Using Python as an extension language IS NOT what tools like SWIG, SIP, Boost.Python, etc. allow you to do...it is the opposite.

If you've ever wanted to use Python in an application written in another language, then you've wanted to use Python as an extension language.

By embedding a Python interpreter into an application for executing specific Python code, one has effectively extended the application with that Python code.

What does it mean to use Python

as an extension language?

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

Quickly prototype a new module

Utilize Python's vast libraries

Reuse code already written in Python

...and all the other advantages of Python which may not be available in the host language (object-oriented, byte-compiled, dynamically typed, platform-independent, easy to maintain, etc.)

Why would someone use Python as an

extension language?

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

Create a wrapper using the Python C API for each Python function to be exposed, as shown in the following steps:

note: the following example uses a simple string-based approach for dealing with the embedded Python interpreter...for an example which makes more extensive use of Python objects, see:

http://python.org/doc/current/ext/pure-embedding.html

How does one go about using Python as an

extension language?

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

Initialize a Python interpreter and import the Python module (if not already done)

file: num2eng.c – C wrapper for num2eng.py (see ex1-C directory)

How does one go about using Python as an

extension language? (cont)

#include <Python.h>

extern int Py_VerboseFlag; /* print out all imports, loaded modules, etc. */

extern int Py_NoSiteFlag; /* load the site-wide configuration */

...

if( !Py_IsInitialized() ) {

Py_VerboseFlag = 0;

Py_NoSiteFlag = 1;

Py_Initialize();

PyRun_SimpleString( (char*)"import num2eng" );

}

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

Map / convert all function arguments from C to Python

file: num2eng.c

How does one go about using Python as an

extension language? (cont)

static char runString[10000];

...

char* num2eng( int num ) {

char* retString = NULL;

if( !Py_IsInitialized() ) {

Py_VerboseFlag = 0;

Py_NoSiteFlag = 1;

Py_Initialize();

PyRun_SimpleString( (char*)"import num2eng" );

}

sprintf( runString, "result = num2eng.num2eng( %d )", num );

...

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

Execute the function using the embedded interpreter

file: num2eng.c

How does one go about using Python as an

extension language? (cont)

...

sprintf( runString, "result = num2eng.num2eng( %d )", num );

PyRun_SimpleString( runString );

...

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

Extract the result from the interp

file: num2eng.c

How does one go about using Python as an

extension language? (cont)

...

static PyObject* evalModule;

static PyObject* evalDict;

static PyObject* evalVal;

...

PyRun_SimpleString( runString );

/*

* evalModule, evalDict, and evalVal are all borrowed references

* ...no DECREF calls should be made

*/

evalModule = PyImport_AddModule( (char*)"__main__" );

evalDict = PyModule_GetDict( evalModule );

evalVal = PyDict_GetItemString( evalDict, "result" );

...

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

Convert result from Python to C, check for any errors

file: num2eng.c

How does one go about using Python as an

extension language? (cont)

/*

* evalModule, evalDict, and evalVal are all borrowed references

* ...no DECREF calls should be made

*/

evalModule = PyImport_AddModule( (char*)"__main__" );

evalDict = PyModule_GetDict( evalModule );

evalVal = PyDict_GetItemString( evalDict, "result" );

if( evalVal == NULL ) {

PyErr_Print();

exit( 1 );

} else {

/*

* PyString_AsString returns char* repr of PyObject, which * should not be modified in any way...this should probably be * copied for safety

*/

retString = PyString_AsString( evalVal );

}

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

2) Create a header file for the extension module :

file: num2eng.h

How does one go about using Python as an

extension language? (cont)

/*

* returns a string pointer to the English

* representation of the number passed in

*/

char* num2eng( int num );

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

3) Use the extension in your application :

file: HelloWorld_PyExt.c

How does one go about using Python as an

extension language? (cont)

#include <stdio.h>

#include <time.h>

#include <num2eng.h>

int main( int argc, char** argv ) {

time_t t;

time( &t );

printf( "Hello World...\n" );

printf( "%s\n(%d) seconds have passed since the Epoch.\n", num2eng( t ), t );

return 0;

}

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

4) Determine the include paths, libraries, and compiler/linker

options needed :

How does one go about using Python as an

extension language? (cont)

$ python

>>> import distutils.sysconfig

>>> distutils.sysconfig.get_config_var('INCLUDEPY')

'/usr/include/python2.1'

>>> distutils.sysconfig.get_config_var('LIBPL')

'/usr/lib/python2.1/config'

>>> distutils.sysconfig.get_config_var('LIBRARY')

'libpython2.1.a'

>>> distutils.sysconfig.get_config_var('SYSLIBS')

'-lm'

>>> distutils.sysconfig.get_config_var('LIBS')

'-ldl -lpthread -lutil'

>>> distutils.sysconfig.get_config_var('MODLIBS')

>>> distutils.sysconfig.get_config_var('LINKFORSHARED')

'-Xlinker -export-dynamic'

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

5) Compile the wrapper and link with the application and libpython.a :

How does one go about using Python as an

extension language? (cont)

cc -c -I. -I/usr/include/python2.1 HelloWorld_PyExt.c

cc -c -I. -I/usr/include/python2.1 num2eng.c

cc -o HelloWorld_PyExt HelloWorld_PyExt.o num2eng.o

/usr/lib/python2.1/config/libpython2.1.a

-lm -ldl -lpthread -lutil -Xlinker -export-dynamic

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

6) Enjoy your application, knowing you can easily prototype new functionality and extend the capabilities of it easier than ever using Python :

How does one go about using Python as an

extension language? (cont)

$ ./HelloWorld_PyExt

Hello World...

one billion, seventy eight million, nine hundred and seventy three thousand,

six hundred and forty seven

(1078973647) seconds have passed since the Epoch.

$ ./HelloWorld

Hello World...

1078973644 seconds have passed since the Epoch.

boring...

exciting!

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

What other things need to be considered when

using Python as an extension language?

Packaging ("frozen" or "warm")

cut-n-paste freeze.py output and set Py_FrozenFlag,

or set PYTHONPATH

Linking in libpython and any other libraries / building a specialized libpython

add C packages in Python distribution to Modules/Setup.local

so they are linked in statically if needed

Initializing the embedded interpreter

extend the embedded Python interpreter with C/C++ extensions

Type conversions

Debugging

Runtime speed / overhead

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

User creates an “interface file” which describes the Python module...including classes, functions, and data types

Same interface file is used for mapping Python to both to C and Tcl, ensuring consistency

Elmer generates a C wrapper for compiling into a C/C++ app or a custom Tcl interpreter based on contents of interface file

If the -frozen option is given, Elmer will use freeze.py (if available) to create a C wrapper with Python code “frozen” in

Is there an easier way to create an interface

to a Python module?

YES!

Elmer is an interface generator for Python modules which

allows them to be used as extensions to C or Tcl.

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

A common complaint: “Why isn't there a key binding in Pico to convert English to Pig Latin, and back again?”

This functionality is easily written in Python...define the Elmer interface for the functions implemented in piglatin.py

file: piglatin.elm – Elmer interface for piglatin.py (see ex2-C_Elmer dir)

Elmer example – extending a

C application with Python

# tell Elmer the name of the module...this is used

# for prefixes and the initial "import" call, so

# leave off the .py extension, just like import

#

module piglatin

#

# define the functions to be exposed and their

# return and arg types, similar to a C prototype

#

string piglatin( string englishTextString )

string depiglatin( string piglatinTextString )

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

Run Elmer on the interface file to generate the C wrapper

Elmer example – extending a

C application with Python (cont)

$ elmer -int piglatin.elm piglatin.py

$ ls

piglatin.c piglatin.elm piglatin.h piglatin.py

$ more piglatin.c

...

char* piglatin(char* arg0) {

ElString __piglatinRunString = elStrNew();

char* retVal;

piglatin_assertInitialized();

elStrAppendString( __piglatinRunString, "__piglatinObj" );

elStrAppendString( __piglatinRunString, " = piglatin.piglatin( " );

elStrAppendString( __piglatinRunString, "\"\"\"" );

elStrAppendString( __piglatinRunString, arg0 );

elStrAppendString( __piglatinRunString, "\"\"\"" );

elStrAppendString( __piglatinRunString, " )" );

...

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

Add the key-binding, and appropriate code to Pico source files

Elmer example – extending a

C application with Python (cont)

KEYTAB keytab[NBINDS] = {

...

{CTRL|'P', backline},

{CTRL|'Q', piglatinregion},

{CTRL|'R', insfile},

{CTRL|'S', depiglatinregion},

...

File: ebind.h

File: efunc.h

...

extern int piglatinregion PROTO((int, int));

extern int depiglatinregion PROTO((int, int));

...

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

Add the key-binding, and appropriate code to

Pico source files (cont)

Elmer example – extending a

C application with Python (cont)

File: region.c

...

#include <piglatin.h>

...

while( tmpBuff[i] != '\0' ) {

if( tmpBuff[i] != '\n' ) {

lineBuff[j] = tmpBuff[i];

j++;

} else {

lineBuff[j] = '\0';

pigLatinString = piglatin( lineBuff );

k = 0;

while( pigLatinString[k] != '\0' ) {

kinsert( pigLatinString[k] );

k++;

}

...

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

Compile the Elmer output, modified Pico sources, and link with libpython, libelmer, and all other required libraries (edit the Makefile)

Elmer example – extending a

C application with Python (cont)

$ make

...

cc -c -I. -I/usr/include/python2.2 -I/usr/local/include/elmer piglatin.c

ar -rc libpiglatin.a piglatin.o

...

cc -g -DDEBUG -I.. -Dlnx -DJOB_CONTROL -DPOSIX -DMOUSE main.o libpico.a

-lncurses libpiglatin.a /usr/local/lib/elmer/libelmer.a

/usr/lib/python2.2/config/libpython2.2.a -ldl -lutil -lm -lnsl

-Xlinker -export-dynamic -o pico

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

Use the new Pico key binding to convert sensitive text to

uncrackable Pig Latin!

Elmer example – extending a

C application with Python (cont)

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

Create new instances of Python classes, lists, dictionaries, etc.

in C++...use Python objects “natively” in C++

Demonstrate by writing a “config file” parser for a C++ application in Python (“config file” syntax looks remarkably like Python...)

Values returned for variables defined in the config file can be strings, ints, floats, lists, dictionaries, etc.

Elmer example – Using

Python objects in C++

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

File: configfile.py

Elmer example – Using

Python objects in C++ (cont)

#

# class which reads a “config file” (variable assignments using

# Python syntax) and allows queries of the files contents

#

class configfile :

def __init__( self, fileName ) :

self.fileName = fileName

self.VarVals = {}

execfile( fileName, globals(), self.VarVals )

def __del__( self ) :

print "DELETING CF INSTANCE FOR: %s" % self.fileName

def getFileName( self ) :

return self.fileName

def getVars( self ) :

return self.VarVals.keys()

def getValue( self, var ) :

return self.VarVals[var]

...

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

File: configfile_cpp.h – C++ wrapper for Elmer-generated output

Elmer example – Using

Python objects in C++ (cont)

class configfile {

public :

configfile( char* fileName );

configfile( const configfile& cf );

~configfile();

const char* getFileName();

CFObj getVars();

CFObj getValue( char* val );

CFObj getValue( const CFObj& val );

private :

int d_id;

void assertInitialized();

};

class CFObj {

public :

enum CFObjType {CFUNKNOWN, CFINT, CFSTRING,

CFFLOAT, CFDOUBLE, CFLIST, CFMAP};

CFObj( int id );

CFObj( const CFObj& cfo );

~CFObj();

int id() const;

CFObjType type() const;

int getInt() const;

char* getString() const;

float getFloat() const;

double getDouble() const;

int length() const;

CFObj keys() const;

CFObj operator[]( const CFObj& k ) const;

CFObj operator[]( int k ) const;

CFObj operator[]( float k ) const;

CFObj operator[]( double k ) const;

CFObj operator[]( char* k ) const;

private :

int d_id;

CFObjType d_type;

};

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

File: configfile_cpp.cpp – C++ wrapper for Elmer-generated output

Elmer example – Using

Python objects in C++ (cont)

CFObj::CFObj( int id ) {

d_id = id;

switch( getType( id ) ) {

case 1 :

d_type = CFINT;

break;

case 2 :

d_type = CFSTRING;

break;

...

CFObj::CFObj( const CFObj& cfo ) {

d_id = cfo.d_id;

d_type = cfo.d_type;

}

CFObj::~CFObj() {

delete_obj( d_id );

}

...

Configfile::configfile( char* fileName ) {

assertInitialized();

d_id = configfile_create( fileName, objCnt++ );

}

...

configfile::~configfile() {

delete_obj( d_id );

}

...

CFObj configfile::getVars() {

return CFObj( configfile_getVars( d_id, objCnt++ ) );

}

CFObj configfile::getValue( char* var ) {

return CFObj( configfile_getValue( d_id, var, objCnt++ ) );

}

CFObj configfile::getValue( const CFObj& var ) {

if( var.type() != CFObj::CFSTRING ) {

throw CFException( "cannot call getValue(<CFObj>)

with a non-string CFObj" );

}

return CFObj( configfile_getValue( d_id, var.getString(),

objCnt++ ) );

}

...

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

File: configfile.elm – interface file describing the functions/classes in	configfile.py

Elmer example – Using Python objects in C++ (cont)

module configfile

#

# tell Elmer to "guess" on how to convert an SCObj into

# the equivalent Tcl object...obviously for Tcl only

#

type SCObj g

class configfile {

configfile __init__( string fileName ) -> create

string getFileName()

list getVars()

SCObj getValue( string varName )

}

#

# these helper functions would not be used in a Tcl interface, since

# Tcl supports native lists and associative arrays (dictionaries)

#

# return vals for getType():

# 0=UNKNOWN, 1=INT, 2=STRING, 3=FLOAT, 4=DOUBLE, 5=LIST, 6=DICT

int getType( SCObj obj )

int extractInt( SCObj obj )

string extractString( SCObj obj )

float extractFloat( SCObj obj )

double extractDouble( SCObj obj )

int getListLength( SCObj obj )

SCObj getNthItemInList( SCObj obj, int n )

SCObj getKeys( SCObj obj )

SCObj getItemInMapIntKey( SCObj obj, int key )

SCObj getItemInMapStringKey( SCObj obj, string key )

SCObj getItemInMapFloatKey( SCObj obj, float key )

SCObj getItemInMapDoubleKey( SCObj obj, double key )

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

Elmer example – Using

Python objects in C++ (cont)

ostream& operator<<( ostream& ostr, const CFObj& cfo ) {

CFObj::CFObjType t = cfo.type();

...

} else if( t == CFObj::CFMAP ) {

ostr << "{";

CFObj keys = cfo.keys();

int numKeys = keys.length();

for( int i = 0; i < numKeys; i++ ) {

ostr << keys[i];

ostr << " : ";

ostr << cfo[keys[i]];

if( i+1 < numKeys ) {

ostr << ", ";

}

}

ostr << "}";

} else if( t == CFObj::CFINT ) {

ostr << cfo.getInt();

...

File: configfile_cpp.cpp – C++ wrapper for Elmer-generated output, showing the stream operator for CFObj

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

File: CFPrinter.cpp – C++ program which prints the contents of a config file

Elmer example – Using

Python objects in C++ (cont)

#include <configfile_cpp.h>

int main( int argc, char** argv ) {

if( argc != 2 ) {

cout << "USAGE: " << argv[0] << " <config file>" << endl;

exit( 1 );

}

configfile cf( argv[1] );

CFObj vars = cf.getVars();

cout << "ALL VARS: " << vars << "\n" << endl;

int numVars = vars.length();

for( int i = 0; i < numVars; i++ ) {

cout << "VAR: " << vars[i] << " VAL: " << cf.getValue( vars[i] ) << endl;

}

cout << "PI = " << cf.getValue( "dictionary" )[cf.getValue( "pi" )] << endl;

return 0;

}

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

Run Elmer, compile the Elmer output, C++ sources, and link with libpython, libelmer, and all other required libraries.

$ elmer -int ../configfile/configfile.elm ../configfile/configfile.py

$ cc -c -I. -I/usr/include/python2.1 -I/usr/local/include/elmer configfile.c

$ g++ -c -I. -I/usr/include/python2.1 -I/usr/local/include/elmer configfile_cpp.cpp

$ ar -rc libconfigfile.a configfile.o configfile_cpp.o

$ g++ -I. -o CFPrinter CFPrinter.cpp libconfigfile.a

/usr/lib/python2.1/config/libpython2.1.a /usr/local/lib/elmer/libelmer.a

-lpthread -ldl -lutil -lm -Xlinker -export-dynamic

Elmer example – Using

Python objects in C++ (cont)

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

Elmer example – Using

Python objects in C++ (cont)

$ CFPrinter example.cf

ALL VARS: ["pi", "barlist", "foo", "foolist", "dictionary", "bar"]

VAR: "pi" VAL: "PI"

VAR: "barlist" VAL: [3, 4, "BAR", [1, 2, "FOO"]]

VAR: "foo" VAL: "FOO"

VAR: "foolist" VAL: [1, 2, "FOO"]

VAR: "dictionary" VAL: {"PI" : 3.14159, "key1" : 3, "key2" : 5}

VAR: "bar" VAL: "BAR"

PI = 3.14159

DELETING CF INSTANCE FOR: example.cf

File: example.cf

...

foo = "FOO"

bar = "BAR"

foolist = [1, 2, "FOO"]

barlist = [3, 4, "BAR", foolist]

pi = "PI"

dictionary = {"key1":3, "key2":5, pi:3.14159}

CFPrinter output:

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

Elmer example – Using

Python objects in Tcl

Create new instances of Python classes, lists, dictionaries, etc.

in C++...use Python objects “natively” in Tcl

Use the same example as shown previously in C++:

Demonstrate by writing a “config file” parser for a Tcl application in Python (“config file” syntax looks remarkably like Python...)

Values returned for variables defined in the config file can be strings, ints, floats, lists, dictionaries, etc.

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

File: configfile.py – same as file used in C++ example

Elmer example – Using

Python objects in Tcl (cont)

#

# class which reads a “config file” (variable assignments using

# Python syntax) and allows queries of the files contents

#

class configfile :

def __init__( self, fileName ) :

self.fileName = fileName

self.VarVals = {}

execfile( fileName, globals(), self.VarVals )

def __del__( self ) :

print "DELETING CF INSTANCE FOR: %s" % self.fileName

def getFileName( self ) :

return self.fileName

def getVars( self ) :

return self.VarVals.keys()

def getValue( self, var ) :

return self.VarVals[var]

...

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

File: configfile.elm – interface file describing the functions/classes in	configfile.py – same as C++ example

Elmer example – Using Python objects in Tcl (cont)

Module configfile

#

# tell Elmer to "guess" on how to convert an SCObj into

# the equivalent Tcl object...obviously for Tcl only

#

type SCObj g

class configfile {

configfile __init__( string fileName ) -> create

string getFileName()

list getVars()

SCObj getValue( string varName )

}

#

# these helper functions would not be used in a Tcl interface, since

# Tcl supports native lists and associative arrays (dictionaries)

#

# return vals for getType():

# 0=UNKNOWN, 1=INT, 2=STRING, 3=FLOAT, 4=DOUBLE, 5=LIST, 6=DICT

int getType( SCObj obj )

int extractInt( SCObj obj )

string extractString( SCObj obj )

float extractFloat( SCObj obj )

double extractDouble( SCObj obj )

int getListLength( SCObj obj )

SCObj getNthItemInList( SCObj obj, int n )

SCObj getKeys( SCObj obj )

SCObj getItemInMapIntKey( SCObj obj, int key )

SCObj getItemInMapStringKey( SCObj obj, string key )

SCObj getItemInMapFloatKey( SCObj obj, float key )

SCObj getItemInMapDoubleKey( SCObj obj, double key )

This section will not be

used in Tcl (but it will be

available) since Tcl

supports native lists and

associative arrays

(dictionaries)

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

File: myTcl.c – Customized Tcl interpreter which contains the configfile extension written in Python

Elmer example – Using

Python objects in Tcl (cont)

#include <tcl.h>

#include <configfile.h>

/*

* called by Tcl_Main for initializing the interp

*/

int Tcl_AppInit( Tcl_Interp* interp ) {

if (Tcl_Init(interp) == TCL_ERROR) {

return TCL_ERROR;

}

/*

* this function is generated by Elmer when the

* -tcl option is specified

*/

return configfileTcl_Init( interp );

}

int main( int argc, char** argv ) {

Tcl_Main( argc, argv, Tcl_AppInit );

return 0;

}

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

File: CFPrinter.tcl – Tcl script which uses the configfile Python extension, and should have same output as C++ CFPrinter.cpp

Elmer example – Using

Python objects in Tcl (cont)

...

if {[llength $argv] != 1 } {

puts "USAGE: $argv0 <config file>"

exit 1

}

set cf [configfile $argv]

set vars [$cf getVars]

puts "ALL VARS: $vars\n"

set numVars [llength $vars]

for {set i 0} {$i < $numVars} {incr i} {

puts "VAR: [lindex $vars $i] VAL: [$cf getValue [lindex $vars $i]]"

}

array set dictionary [$cf getValue dictionary]

puts "PI = $dictionary([$cf getValue pi])"

#

# Tcl will not call Tcl_CmdDeleteProc until it needs to...

#

rename $cf ""

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

Run Elmer, compile the Elmer output & myTcl.c, and link with libpython, libelmer, and all other required libraries.

$ elmer -int ../configfile/configfile.elm ../configfile/configfile.py

$ cc -c -I. -I/usr/include/python2.1 -I/usr/local/include/elmer configfile.c

$ g++ -c -I. -I/usr/include/python2.1 -I/usr/local/include/elmer configfile_cpp.cpp

$ ar -rc libconfigfile.a configfile.o configfile_cpp.o

$ g++ -I. -o CFPrinter CFPrinter.cpp libconfigfile.a

/usr/lib/python2.1/config/libpython2.1.a /usr/local/lib/elmer/libelmer.a

-lpthread -ldl -lutil -lm -Xlinker -export-dynamic

Elmer example – Using

Python objects in Tcl (cont)

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

Elmer example – Using

Python objects in Tcl (cont)

$ CFPrinter example.cf

ALL VARS: ["pi", "barlist", "foo", "foolist", "dictionary", "bar"]

VAR: "pi" VAL: "PI"

VAR: "barlist" VAL: [3, 4, "BAR", [1, 2, "FOO"]]

VAR: "foo" VAL: "FOO"

VAR: "foolist" VAL: [1, 2, "FOO"]

VAR: "dictionary" VAL: {"PI" : 3.14159, "key1" : 3, "key2" : 5}

VAR: "bar" VAL: "BAR"

PI = 3.14159

DELETING CF INSTANCE FOR: example.cf

CFPrinter C++ output:

$ myTcl CFPrinter.tcl example.cf

ALL VARS: pi barlist foo foolist dictionary bar

VAR: pi VAL: PI

VAR: barlist VAL: 3 4 BAR {1 2 FOO}

VAR: foo VAL: FOO

VAR: foolist VAL: 1 2 FOO

VAR: dictionary VAL: PI 3.14159 key1 3 key2 5

VAR: bar VAL: BAR

PI = 3.14159

DELETING CF INSTANCE FOR: example.cf

CFPrinter.tcl output:

Rick Ratzel - rlratzel@users.sourceforge.net

Using Python as an Extension Language

Python is a good choice for an extension language:

allows for quick prototyping of new functionality, something not always as easily possible in other languages.

standard library includes a wide variety of modules which can enhance applications written in other languages.

code is becoming more and more prevalent

...why rewrite when you can reuse?

Elmer allows it to be used in C/C++ and Tcl applications “seamlessly”.

Elmer automatically converts supported types.

Elmer allows Python developers to easily share their code with developers who use other languages.

http://elmer.sourceforge.net

In conclusion...

2004-02-26T10:26:26