elmer http://elmer.sourceforge.net
Elmer allows Python code to run from C, as if it was written in C.
Elmer allows Python code to run from Tcl, as if it was written in Tcl.
For example...
run code in C:
#include<reader.h> int main( int argc, char** argv ) { /* * read /etc/passwd using Python reader class */ int reader1 = reader_create( elNEWID ); int lines1; reader_openFile( reader1, "/etc/passwd" ); lines1 = reader_getLines( reader1, elNEWID ); /* * display parts of the file, use Python findLine & getNthLine functions */ printf( "There are %d lines in /etc/passwd\n", reader_getNumLines( reader1 ) ); printf( "User rlratzel is on line %d\n", findLine( lines1, "rlratzel" ) ); printf( "This is the 4th line: %s\n", getNthLine( lines1, 4 ) ); printf( "This is the 21st line: %s\n", getNthLine( lines1, 21 ) ); return 0; }
which was written in Python:
import re # # class which reads a file into a list of lines # class reader : def __init__( self ) : self.d_lines = [] def openFile( self, fileName ) : fh = open( fileName ) self.d_lines = fh.readlines() fh.close() def getLines( self ) : return self.d_lines def getNumLines( self ) : return len( self.d_lines ) # # function which returns the nth line in a list # def getNthLine( lines, nth ) : return lines[nth] # # function which returns the line num matching the pattern # def findLine( lines, pattern ) : for i, line in enumerate( lines ) : if re.match( pattern, line ) != None : return i return -1
which produces the following output:
There are 24 lines in /etc/passwd User rlratzel is on line 21 This is the 4th line: lp:x:4:7:lp:/var/spool/lpd: This is the 21st line: rlratzel:x:500:500:Rick L. Ratzel:/home/rlratzel:/bin/bash
run the same Python code in Tcl:
# # read /etc/passwd using Python reader class # set readerObj [reader] $readerObj openFile /etc/passwd set lines [$readerObj getLines] # # display parts of the file, use Python getNthLine function # (no need to use Python findLine function since we can use # native Tcl to process native lists) # puts "There are [llength $lines] lines in /etc/passwd" puts "User rlratzel is on line [lsearch $lines *rlratzel*]" puts "This is the 4th line: [getNthLine $lines 4]" puts "This is the 21st line: [getNthLine $lines 21]"
which also produces the following output:
There are 24 lines in /etc/passwd User rlratzel is on line 21 This is the 4th line: lp:x:4:7:lp:/var/spool/lpd: This is the 21st line: rlratzel:x:500:500:Rick L. Ratzel:/home/rlratzel:/bin/bash
Elmer allows developers to write code in Python and execute it in C or Tcl. The resulting interfaces to the Python code generated by elmer is transparent to the C or Tcl user... Python calls appear as native calls ( "foo( 1, "a" )" in Python appears as "foo 1 a" in Tcl, for example) and Python and native data types are automatically mapped (Tcl lists are converted to Python lists, Python dictionaries are returned as Tcl associative arrays, char* becomes a Python string object, etc.). Elmer also supports Python's "freeze" module, allowing a Python developer to deliver a single library consisting of several Python files "frozen" in to the application...no need to set PYTHONPATH or have Python source files accompanying the app.
By simply specifying either the C-mode or Tcl-mode options, developers can use the same Python modules in either C or Tcl programs...the C or Tcl programmer need not know that the module was written in Python (or any other language for that matter).
Elmer has been used in large software projects, where different teams wrote re-usable modules in different languages (namely, Python, Tcl, and C). Elmer has allowed the large number of Python modules written to be seamlessly used in Tcl and C programs without having to re-write them in the native languages.
Elmer allows various data types to pass between Python and C or Tcl as native types (when supported). For example, a Python dictionary of strings to lists-of-floats is automatically converted to a Tcl associative array of strings and lists-of-floats. An int in C is automatically converted to a Python int object. Python objects are even handled and can be passed to other Python code through the native language when the Python type can not be converted to a native type. For example, In the C program above, a Python list was retrieved and passed to another Python function.
Elmer allows developers to leverage the strengths of various languages without the restrictions of language barriers. Developers do not need to learn special APIs or access the internals of the language...all code appears native to the language of the application, even if not written in the host language. The intended interface for the Python module is preserved and not wrapped around obfuscating "eval" calls or other mechanisms which hinder readability and re-usability.
Although the core features of elmer have gone unchanged for several years, and it has been successfully used in a large commercial project by many different kinds of developers, it is still considered beta. Your feedback is greatly appreciated!
Windows Build Mods
Needed to make a couple of changes to get it to build using Microsoft VS.Net 2003:
{{{libTarget = buildEnv.StaticLibrary( target="elmer",
- source=ELMER_C_SRCS )
}}}
instead of:
{{{libTarget = buildEnv.StaticLibrary( target="elmer",
- source=ELMER_C_SRCS + ELMER_H_FILES )
}}}
Also with MS.Net you need to specify CPPFLAGS=/TP on the commandline in order to compile a .c file as C++ (otherwise defaults to C compiler and fails).