Home > Articles > Programming > Python

  • Print
  • + Share This
Like this article? We recommend Glue Logic: A Sticky Business

Glue Logic: A Sticky Business

In this context, glue logic is simply a piece of Python script that allows you to call your legacy C++ programs, with no need to change them. Suppose we have a bunch of such C++ programs that must be called from Python, with the major requirement that we cannot make any changes to the C++ code. In other words, C++ code exists and is in use by real users. We can call it—but not change it!

With this requirement in mind, let's look at an example of the glue logic approach.

Calling C++ Programs from Python

Let's say we have a really simple C++ program (called CPlusPlus0xProject) that we want to call from Python. Listing 1 illustrates an excerpt from the C++ program.

Listing 1—A simple C++ program.

int main() {
        cout << endl << "Now calling doSomeMemoryWork()" << endl;
        doSomeMemoryWork();
        cout << "Now calling getPersonDetails()" << endl;
        getPersonDetails();

        return 0;
}

How do we run this C++ program from Python? This goal is achieved with the Python script in Listing 2.

Listing 2—Python invocation of a C++ program.

import os, errno
import subprocess as sp

def invokeProgram():
    try:
        print('Just before Python program invocation')
        p = sp.Popen(['/home/stephen/CPlusPlus0xProject'], stdout = sp.PIPE)
        result = p.communicate()[0]
        print('CPlusPlus0xProject invoked'  + result + '\n')
    except OSError as e:
        print('Exception handler error occurred: '  + str(e.errno) + '\n')

if __name__ == '__main__':
    invokeProgram()

In Listing 2, our simple C++ program is invoked from Python by using the subprocess module. The script imports a few standard modules, defines a function, and then has a main section. The C++ program can be anything you like; Listing 2 is essentially the same as running the C++ program directly from the console.

Listing 3 shows the combined Python and C++ program output.

Listing 3—The Python and C++ program output.

Just before Python program invocation
CPlusPlus0xProject invoked
Now calling doSomeMemoryWork()

Function name: doSomeMemoryWork()
Before memory assignment
a = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
b = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
c = cccccccccccccccccccccccccccccc
After memory assignment
a = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
b = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
c = cccccccccccccccccccccccccccccc
Now calling getPersonDetails()
Person just created is: John Doe
Person name = John Doe
Now inside the Person class destructor

Why go to the trouble of using Python like this? Isn't it just as easy to run the C++ program from the console?

Well, using Python like this gives you a great deal more power than is the case with the console. For one thing, you can take advantage of Python's exception-management facilities—this is the try-except block in Listing 2. If anything goes wrong inside the Python exception block, you'll see a message printed on the console. For example, let's change this line in Listing 2:

p = sp.Popen(['/home/stephen/CPlusPlus0xProject'], stdout = sp.PIPE)

to this:

p = sp.Popen(['./home/stephen/CPlusPlus0xProject'], stdout = sp.PIPE)

Running this erroneous Python code results in the following program output:

Just before Python program invocation
Exception handler error occurred: 2

Notice the exception that has been caught and reported. Now, you might be thinking, "This fellow is very pessimistic in outlook, worrying about exceptions from the word 'go.'" This is a good point, but exceptions are generally an unavoidable fact of life. Exception handling is perhaps not the most glamorous of areas to code, but working hard on your exception logic makes for a more solid end product. This in turn provides for an improved end-user experience.

Clearly, the code being executed in these examples is very simple. But as you scale up the size of both the Python code and the C++ programs, you'll begin to see the power of the glue logic approach. A large number of C++ programs can be invoked from a fairly simple Python script.

Now let's take a closer look at Python exceptions.

Python Exceptions

Python has a powerful exception-management facility and is substantially documented online. Listing 4 shows a typical exception example.

Listing 4—Python I/O exception management.

try:
    fh = open('/home/stephen/myFile.txt', "w")
    fh.write("A test file.")
except IOError as e:
    print('Exception handler error occurred: '  + str(e.errno) + '\n')
else:
    print 'Successfully updated file.'

The script in Listing 4 opens a file in write mode and then attempts to write to the file. If no errors occur, the output should be that associated with the else clause:

Successfully updated file.

If an IOError exception occurs, the except clause is executed.

The Python exception code we've seen so far is very similar to the equivalent Java (or even C++) mechanism. The major merit of such exception handling is that errors can be handled close to where they occur. If the code in question can't handle the exception, at the very least it should document the exception in a logfile and then rethrow it. The latter scenario then gives higher-level code (that is, the calling code) a chance to handle the exception. Think of this as the rule:

Exceptions are inconvenient, but they should never be ignored or swallowed by code without a really good reason.

Given that Python has strong exception-support facilities, is it a full development language?

  • + Share This
  • 🔖 Save To Your Account