Tutorial

Simple example

from embedc import C
a=[1,4,9]
result = C("""
	for (int i=0; i<3; i++) {
		sum += a[i]*a[i];
	}
	return sum;
""")
print result

The example above accesses a Python array and computes the sum of the squares. Notice how "a" is accessed directly. In this example, when the C function is called, the module creates copies of all local and global variables (keeping the same names) in the C program, with the same type as the original. In the case above "a" is a C "int[]". At the end, the function copies back any changed C variables back to their Python source.

This also works within arrays, so in the follwing code, "a" would be [1,16,81]:

a=[1,4,9]
C("""
	for (int i=0; i<3; i++) {
		a[i] = a[i]*a[i];
	}
""")
print a

Strings

Strings are converted to a "char *" C type. Changes to the string must be done with care to consider memory allocation problems. Consider the following code:

s='123'
C('s="abc";')

"s" at then end would be "abc". Care must be taken when allocating memory for strings to avoid memory leaks. In the example above, there is no leak because "abc" is a const string.

The following code leaks memory:

s="123" 
C('s=strdup("abc")')

To solve this problem, use the GLOBAL and POST directives. GLOBAL declares global C variables and POST executes code after all the C variables have be saved in Python.

s="123" 
C("""
GLOBAL char *sav;
sav=strdup("abc")
s = sav
POST free sav
""")

GLOBAL creates a global C variable. POST is executed after the function returns and the variable transfers have occurred.

Precompiled Code

In the examples above, the code is compiled every time C is called. In some cases, particularly inside loops, it's helpful to compile the code once and reuse it. For example:

a=(1,6,4,3,2)
for i in a:
    embedc.inline_c_precompile("""
        IMPORT int i
        complex_calc(i)
    """)

When you call inline_c_precompile, the embedc module will read the original source code file, pick out the "inline_c_precompile" key word and read all the text between the triple-quotes. The text must be enclosed in triple-quotes, and the C/C++ code has to be in separate lines between them. This is done to speed up processing.

In addition, because the function has no run-time context when it is compiled, all variables must be defined with the IMPORT directive. The IMPORT keyword is followed by the type and the variable. Types are most C types (int, double, etc.) that ctypes supports. For strings, the type should be "string", not "char *" to differentiate from a Python array of chars.

Callbacks

Sometimes, it is useful to call a Python function from C. This is done by using the DEF directive. For example:

def myfunc(x, y):
    return x+y
r = C("""
    DEF int myfunc int int
    return myfunc(10,11);
    """)

The DEF keyword is followed by the return type, the function name, and the types of all the arguments. Note: I am considering making it more C-like by requiring parenthesis and commas as in "DEF int myfunc(int, int)" and may do so in the future if I need to support more complex types (like pointers and arrays). Right now only simple types (int, double, string) are supported.