Channels ▼
RSS

Design

Speeding-Up Software Development Using Embedded Scripting


Harry H. Cheng is a professor at the University of California, Davis. He can be reached at hhcheng@ucdavis.edu.


Embedded scripting is increasingly gaining popularity in design of software systems and applications. In the programming paradigm of embedded scripting, an interpreter or scripting engine is embedded into a binary application program. The application can execute script code through the embedded interpreter. The script code can also invoke binary code. Although a powerful embeddable interpreter can speed-up software development and deployment significantly, the power and capabilities of this programming paradigm are yet to be explored and fully utilized.

For example, if a C/C++ interpreter is embedded in an automated program for testing hardware and software, quality assurance engineers are able to access binary C functions and C++ member functions from C/C++ testing scripts. A binary application program can be used to test different products by just invoking different scripts that can be entered from the GUI or loaded from files. As another example, an embedded interpreter can be used to customize a product for different customers and applications, and extra functionality can be added to applications specific to a particular customer's needs without changing the standard product. By using scripts, executed at the defined points from the application, customer-specific behaviors can be implemented.

Many embeddable interpreters are available for embedded scripting— Tcl/TK, Python, Ch, and Lua, among others. However, it's most desirable if the same language is used for both native binary code and scripting code. Otherwise, there is overhead and complexity in sharing the data between binary space and script space.

C and C++ are most commonly used to develop binary applications. For application programs written in C/C++, embedding a C/C++ interpreter is the most logical choice. The memory, functions, and header files can be seamlessly shared by both application program written in C/C++ and C/C++ scripts.

Listing One shows how a C/C++ interpreter can be easily embedded in an application program as a scripting engine. In this example, Ch (an embeddable C/C++ interpreter from SoftIntegraton, www.softintegration.com) is used. The program includes the header file embedch.h, which defines some macros, data types, and function prototypes for embedded Ch. The program first initializes an embedded Ch interpreter by the API:


Ch_Initialize(&interp, NULL);

The function func() is loaded in the interpreter by:


Ch_AppendRunScript(interp, code);

This script function is invoked by:


Ch_CallFuncByName(interp,"func", &retval, x, a);

The variable retval contains the returned value. The variable x is passed to function func(). The memory for array a is shared in both binary and script space. Finally, the interpreter is closed by function call:


Ch_End(interp);


The output from execution of the compiled and linked binary program embedch.exe is as follows:


x = 10.000000
a[1] in func=2
a[1] in main=20
retval = 30

When an interpreter is embedded into an application, it becomes a part of the application. If the interpreter has a memory leak for running each script code, this memory leak is reflected in the application. Therefore, the interpreter must be reliable and robust. When an error occurs, the interpreter should not crash and all the dynamically allocated memory for the offending code should be released. Thus, it is more challenging in error handling in an interpreter than in a compiler. A robust interpreter should recover from errors smoothly.

/* File: embedch.c */
#include <stdio.h>
#include <embedch.h>
char *code = "\
   int func(double x, int *a) { \
      printf(\"x = %f\\n\", x); \
      printf(\"a[1] in func=%d\\n\", a[1]);\
      a[1] = 20; \
      return 30; \
   }";
int main () {
   ChInterp_t interp;
   double x = 10;
   int a[] = {1, 2, 3, 4, 5}, retval;
   Ch_Initialize(&interp, NULL);
   Ch_AppendRunScript(interp,code);
   Ch_CallFuncByName(interp, "func", &retval, x, a);
   printf("a[1] in main=%d\n", a[1]);
   printf("retval = %d\n", retval);
   Ch_End(interp);
}
}
Listing One


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video