ITworld.com
  Search  
ITworld Home Page ITworld Webcasts ITworld White Papers ITworld Newsletters ITworld News ITworld Topics Careers ITworld Voices ITwhirled Changing the way you view IT
 

Scripted wrappers for legacy applications, Part 3

Unix Insider 1/19/01

Extending scripting languages with C

Cameron Laird and Kathryn Soraiz, Unix Insider

unixinsiderhome
We emphasize wrapping existing applications because it's such good engineering. Suppose, as we did in our previous two columns, that you have a command line application that works correctly -- you just want a GUI with the same functionality. The safest way to achieve that is to keep what you have -- the correct, well-exercised command-line application -- and wrap it with a thin GUI.

Even the smallest change requiring a relinking of a compiled application introduces numerous possibilities for error. That's why we so strongly favor a pipe for IPC -- it fits architectures that reuse what you already have.

However, many other forms of IPC can serve in this role. The most important in the Internet age, of course, is a TCP/IP socket connection. Most scripting languages now support networking quite well. One architecture we often use when scripting existing code is C embedded in a computational server and connected to it with simple, networked GUIs. You may remember that the July installment of Regular Expressions mentioned Effective Tcl/Tk Programming as a good read for scripters, even those who don't use Tcl or Tk. In Chapter 7 of that book, authors Michael McLennan and Mark Harrison work out a nice example of this computational service architecture.

What the authors leave unsaid, though, is that their methods are more or less language-independent. Code a computational server in C or Fortran, with a simple protocol for talking to clients. You can then quickly develop client-side GUIs in any language you choose: Perl/Tk, Tkinter, or something more exotic. The point is not to proliferate technologies, but to realize you're free to combine the ones that best suit different requirements of your projects. Use Fortran and PyQt when both are advantageous; teach the two to communicate and you can enjoy the best of two different worlds.

Extending a scripting processor
Think about:


     print("Hello, world.\n"); 

That is a Perl script. Suppose you've coded a little C function that logs results to a central database. You want to take advantage of the work you've already done, and somehow have the capability to write:


     my_log("Hello, world.\n"); 

in Perl, and have it do what you intend. You want to extend Perl.

Extension is more specialized than the process management we explained earlier. The first two installments of this series demonstrated tiny working programs that illustrated important functionality available in essentially all modern scripting languages. Extension involves several details likely to be specific to a particular compiler, platform, and language; useful code doesn't generalize so transparently.

Our goal in this article is to introduce the vocabulary of language extension, and supply the resources you'll need to pursue the subject with a particular language.

To extend a scripting language with a function coded in C, C++, Fortran, or another language, you usually need:

  1. The function compiled as an object module
  2. A wrapper to match your function with your scripting language
  3. A notification or registration
  4. A way to introduce the wrapper into the scripting language's process space
  5. A script that invokes the wrapper

The last one is usually the easiest -- it might be as easy as replacing print with my_log in a program that already works.

It's impossible to directly extend any of the most common scripting languages with C or Fortran. They must first be wrapped to match the calling conventions of the scripting language implementation. If you have an existing C-coded module:


       void C_my_log(char *text) ... 

you'll write a tiny wrapper:


       RETURN scriptable_my_log(ARGS) 
       { 
               ... 
               C_my_log(...); 
       } 

That kind of wrapping is largely mechanical; several well-supported systems automate the tedium. SWIG, which has been mentioned in Regular Expressions several times in the past 3 years, is the most widely used tool of this kind.

Registration alerts the language processor of an association between my_log (the name of a command or function visible within the extended scripting language) and scriptable_my_log (the name of an implementing C-coded function). This is also easy to automate in most languages, and is another feature of SWIG.

How do the scriptable_my_log and C_my_log objects enter the scripting language's process space? They're most often combined in a shared object, loadable module, shareable library, or dynamically linked library. The new object might have a name like my_log.so or my_log.dll. Then, near the top of a script which uses my_log, a directive loads or imports the library. Once that's done, my_log is just as accessible as any of the scripting language's native functions.

Cultural variation
Tcl and Lua have traditionally been among the easiest languages to extend, and most books on Tcl supply a recipe for building your own extension. That is consistent with the traditional view that Tcl is the glue for things outside itself. Perl, however, is biased toward comprehensiveness. Extending Perl with modules in other languages is regarded as difficult; it was not explicitly mentioned in the authoritative Programming Perl until the third edition. One of the main goals of Perl 6 is to simplify extension authorship.

Don't let any of this intimidate you. Tens of thousands of people have extended scripting languages with C and other languages. Help on the subject is abundant; even tutorials for such specific combinations as Borland C with Python under Windows 95 are available. You, too, can be an extension writer.

Tough advice next time
For the last year, much of Regular Expressions has been cross-language: discussion of ideas that are applicable no matter what language you use. Reader John Wiersba, though, wrote that he

would like to see some more in the way of language comparisons in your column -- the strengths and the weaknesses, pitfalls, best uses, and inappropriate uses. There are just too many scripting languages out there to choose from. If I'm going to learn a new language, I'd like it to be the best available for my task, or, preferably, something suitable for my task with a broad base of other application areas.

John's right. We'll be back in two weeks to address it.

Cameron Laird and Kathryn Soraiz manage Phaseit, a software consultancy just outside Houston.





 
www.itworld.com    open.itworld.com     security.itworld.com     smallbusiness.itworld.com
storage.itworld.com     utilitycomputing.itworld.com     wireless.itworld.com

 
Contact Us   About Us   Privacy Policy    Terms of Service   Reprints  

CIO   Computerworld   CSO   GamePro   Games.net   Industry Standard   Infoworld   ITworld  
JavaWorld   LinuxWorld  MacUser   Macworld   Network World   PC World   Playlist  

DEMO   IDG Connect   IDG Knowledge Hub   IDG TechNetwork   IDG World Expo  

Copyright © Computerworld, Inc. All rights reserved

Reproduction in whole or in part in any form or medium without express written permission of Computerworld Inc. is prohibited. Computerworld and Computerworld.com and the respective logos are trademarks of International Data Group Inc.