Extending C

I love C.  I enjoy being able to implement my ideas quickly in a manner that will compile, with optimization, and run relatively fast.  I also enjoy, academically, having to truly understand the structures I will be employing.  Without a solid understanding of a concept, I will not be able to implement it directly in C; this is a sanity check for my learning.

C is also a beautiful system for processing data very fast at a low level.  For example, I am presently writing a line and circle detection algorithm for a set of robots that will be competing in the RoboCup competition.  The vision processing that provides the foundation environment from which I will be able to work is all rapidly implementable at this level.  The senior level course we teach on basic computer vision focuses mainly on the algorithms, but then switches to matlab for their use in projects.  It is certainly one thing to effectively use a Sobel filter to prepare an image for applying the Hough transform, however, it is another thing entirely to understand these two transforms enough to be able to write them.  There is certainly no doubting that the algorithms in matlab are expertly written and are the pinnacle of optimization, but there is also no question that matlab cannot be run on an embedded system in a realtime environment.

As much as I love C, I also realize that there are features of other languages that are simply foolish to attempt to emulate within C.  Imagine trying to create an associative array that is able to store key:value pairs, where either, or both, of those elements are strings.  This is certainly implementable, though it would certainly be significantly more daunting to do so than to just fire up Python and use a dictionary structure.   For rapid prototyping, I would be a fool to spend half a day on this problem in C, when an entry-level student could write a similar program in Python in fifteen minutes flat.

It would also be idiotic to, in the same program, expect Python to run tight loops of operations on pixel-arrays in anywhere near the time that it could be done in C.  Generally, this predicament has led me to weigh the benefits and problems with different languages and then pick the language with the more natural implementation and runtime speed for the problem at hand.  In many cases, however, this chosen language will be underperforming in select areas.  There is a third solution that has always been in the back of my brain, but never actually made it to my conscious thought-process.  This is to use the more powerful, low-level language, and then extend its functionality through the use of an embedded scripting language.

Yesterday I finally got around to turning this dormant thought into reality.  I wrote a quick program, for a classroom demonstration, that adds the ‘dictionary’ functionality of an associative array into C, using embedded lua code.  This has the advantages of using the compiled C for speed and being able to use the table data structure of lua to emulate a ‘hashmap’ or ‘dictionary’ feature without having to do any heavy C coding.  In fact, writing a full-featured associative array in lua was precisely this easy:

hashmap = {}
function addEntry(key, value)
hashmap[key] = value

function retrieveEntry(key)

All I had to do was create matching functions in C that pushed all of the arguments onto an argument stack, made the lua function call, allowed lua to run its own code and return their value(s), which are then received in the return stack and processed by C.  At this point, C is back to its normal compiled efficiency to do with that code what it needs to.

Here is one of the the function calls I used to interface with the lua functions:

int hashSearch(char *name) {
int errno;
lua_getglobal(LS, “retrieveEntry”); // Designate the function in lua to call
lua_pushstring(LS, name); // Push in the parameter
// Call the function with 1 argument, expecting back 1 return value
errno = lua_pcall(LS, 1, 1, 0);
if(errno) return 0;
// This function retrieves the first element on the return stack from lua  and converts it to a number.
else return lua_tonumber(LS, -1);

Code format on this blog notwithstanding, it’s not a terribly complicated process.  The call stack is manually set, which gives the benefit of allowing multiple arguments and multiple return values from lua.   There is also very little overhead code to create the lua environment for embedding.

Once embedded and compiled using the lua libraries, the executable is portable with the added benefit that the .lua script is still just a plaintext lua script file.  This makes end-used modifications effortless by allowing your users to write or modify the lua code which is executed by the compiled code, without having to recompile.  Obviously, that would be very bad to play with for this example, but, when done properly, lua extensions to your codebase can provide users a great deal of flexibility and power over the program without any need to recompile.

This was a fun experiment and something that I look forward to practically using at a later time.

Kevin Andrea

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>