http://www.developer.com/net/cplus/article.php/3570016/Expose-Your-CC-Programs-Internal-API-with-a-Quick-SWIG.htm
My previous installment, "Add Embedded Scripting to Your C++ Application," showed how you can use the C Scripting Language (CSL) to move your application from a strictly GUI- or command line-based system to one that fully embraces end-user programmability. In the spirit of a Zen koan, this article looks at an example of the "opposite" of adding scripting to your application: making your application's internal API callable from within Perl scripts. Fortunately, you can do this without resorting to obscure Interface Definition Languages (IDLs), CORBA, COM, RPC, stubs, or any of those legacy framework generators. The Simplified Wrapper and Interface Generator (SWIG) is a software development tool that connects programs written in C and C++ with a variety of scripting languages. SWIG is used with different types of languages, including all your favorites: Perl, PHP, Python, Tcl, Ruby, and most recently Lua. The list of supported languages even includes non-scripting languages such as C#, Common Lisp variants, Scheme, Java, Modula-3, and Objective Caml. However, SWIG is most commonly used to create high-level interpreted or compiled programming environments, user interfaces, and as a tool for testing and prototyping C/C++ software. SWIG also can export its parse tree in the form of XML and Lisp s-expressions. You can freely use, distribute, and modify SWIG for commercial and non-commercial use. SWIG opens up a lot more possibilities than just API automation. Lok briefly at some these before digging into the details of making SWIG work for you: Suppose you want to expose the functions in a Probability Library for use with a Perl script. The probability functions compute factorials, permutations, and probably a lot of other boring stuff. To show off a bit, you wrap the legendary Win32 API's MessageBox() function from the venerable user32.lib as well. Written in C, it looks like stats.c in Listing 1. Listing 1. stats.c Next, in lieu of an obfuscatory IDL, COM, CORBA, or other type specification of interfaces, you use (gasp!) the slightly enhanced header file (stats.i) shown in Listing 2. Listing 2. stats.i Enhanced Header File Before you go any further, you need to install some form of SWIG. If you are working from a Windows or Mac platform, you probably want to start with some precompiled binaries from the SourceForge site. SWIG for Win32 (or SWIGWIN) doesn't come with a fancy installer: you simply unzip it and set some environment variables. You can retarget SWIG to the Cygwin or MinGW Unix-for-Windows environments by recompiling the system. I use Cygwin Perl for most workaday Perl scripting, but because you likely will be integrating with Visual Studio C++-built Win32 apps, I chose to try the nsPerl 5.005_03 that the docs recommended. For nsPerl, my environment is as follows: Next, you need to discover which compiler flags your nsPerl was built with to produce linkable code later: Now, you can invoke the SWIGWIN generator to produce the stats_wrap.c wrapper based on the stats.i interface file (from Listing 2): Lastly, you compile and link both your original code and the wrapper code in one step, using the ccopts discovered above: Now, step back and look at what you've actually produced so far. Based on your two input files (stats.c and stats.i), you have churned out the following: Listing 3. Generated stats.pm File Now, you finally can have some fun and call your "new" stats library from Perl. Construct the simple Perl program in Listing 4, which should be obvious to any coder: Listing 4. A Simple Perl Program for Our Stats Library The output is the dialog box shown below! What I've demonstrated thus far (I hope) is a relatively quick and painless way of exposing your C/C++ program's internal API to the machinations of any scripting language. Although I chose to use Perl, you could easily generate corresponding modules for Python, Java, and Lua in just a few minutes more. SWIG covers the vast majority of C++ classes and language features: references, pointers to members, multiple inheritance, overloaded functions and operators, smart pointers, STL data types, namespaces, and much more. The only known hole currently is the wrapping of nested classes, but the nearly all C/C++ programs are eminently "SWIGable." So what are you waiting for? Victor Volkman has been writing for C/C++ Users Journal and other programming journals since the late 1980s. He is a graduate of Michigan Tech and a faculty advisor board member for Washtenaw Community College CIS department. Volkman is the editor of numerous books, including C/C++ Treasure Chest and is the owner of Loving Healing Press. He can help you in your quest for open source tools and libraries, just drop an e-mail to sysop@HAL9K.com.
Expose Your C/C++ Program's Internal API with a Quick SWIG
December 12, 2005
The Simplified Wrapper and Interface Generator
Your First SWIG: A Probability Library
double pi = 3.14159; //not used yet
int factorial(int n) {
if (n <= 1)
return 1;
else
return n*factorial(n-1);
}
int permutation(n,r)
{
return factorial(n) / factorial(n-r);
}
#include <windows.h>
int ShowAMessage(long hWnd, char *lpText, char *lpCaption,
unsigned int uType)
{
//WIN32 API call
return MessageBox(hWnd, lpText, lpCaption, uType);
}
/* stats.i */
%module stats
%{
/* Put header files here or function declarations like below */
extern double pi;
extern int factorial(int n);
extern int permutation(int n,int r);
extern int ShowAMessage(long hWnd, char *lpText,
char *lpCaption,
unsigned int uType);
%}
extern double pi;
extern int factorial(int n);
extern int permutation(int n,int r);
extern int ShowAMessage(long hWnd, char *lpText, char *lpCaption,
unsigned int uType);
set PERL5_INCLUDE=D:\nsPerl5.005_03\lib\CORE
set PERL5_LIB=D:\nsPerl5.005_03\lib\CORE\perl.lib
perl -MExtUtils::Embed -e ccopts
-Od -MD -DNDEBUG -DWIN32 -D_CONSOLE -DNO_STRICT -
IF:/nsPerl/netsite/nsPerl/WINNT/lib/nsPerl5.005_03\lib\
MSWin32-x86/CORE
swig -perl5 stats.i
cl -Od -MD -DNDEBUG -DWIN32 -D_CONSOLE -DNO_STRICT stats.c
stats_wrap.c /link user32.lib d:\nsPerl5.005_03\lib\MSWin32-x86\
CORE\perl.lib
/DLL /out:stats.dll
Calling Your C Functions from Perl
# This file was automatically generated by SWIG:
package stats;
require Exporter;
require DynaLoader;
@ISA = qw(Exporter DynaLoader);
package stats;
bootstrap stats;
package stats;
@EXPORT = qw( );
1;
use stats;
$answer = stats::factorial(5);
stats::ShowAMessage(0,"5! is $answer","SWIG Testing",0);

Give Your C/C++ Program's Internal API Full Exposure
About the Author