Title: Wrapping C with Perl
1Wrapping C with Perl
2SWIG (Simplified Wrapper and Interface Generator)
- Wraps C with Perl or other computer languages
- Generates the connecting wrapper code for both
C and Perl (or other target language). - C code then compiled and linked into a library
- Perl scripts call Perl wrapper, which in turn
calls C library
3Motivation
- Code high level functionality in Perl
- File, Database I/O
- String manipulation, pattern matching, etc.
- Sorting, organizing data
- Applying functions to elements of arrays
- Filtering out elements from arrays
- Code Toolkit interfaces and computationally
intensive code in C - Need a better way to integrate these two languages
4File Generation
example.i
example.pm
SWIG
example.h
example_wrap.cxx
(other header files)
example_wrap.cxx
example.dylib (MacIntosh)
g
example.cpp
or
example.so (Other Unix Platforms)
(other CPP files)
5SWIG Interface File
- Tells which routines are to be wrapped
- Wraps built-in C/C data types
- Wraps STL vectors and strings
- Can wrap more complex data structures
- Can specify error handling
6Example Interface File
include "exception.i" exception try
action catch (const
stdexception e)
SWIG_exception_fail(SWIG_RuntimeError,
e.what()) module example /
Put headers and other declarations here
/ include "example.h" include
"std_vector.i" include "std_string.i" template(
IntVector) stdvectorltintgt template(DoubleVecto
r) stdvectorltdoublegt include "example.h"
7Running the SWIG Command
- swig c -perl5 example.i
- Produces
- example_wrap.cxx C Wrapper
- example.pm Perl Wrapper
8Compiling and Linking C Example
Make file MacIntosh version all swig
-c -perl5 example.i g -c example.cpp
example_wrap.cxx \ /usr/bin/perl
-MExtUtilsEmbed -e ccopts g -dynamiclib
-single_module -flat_namespace \ -undefined
suppress -o example.dylib example.o
example_wrap.o clean rm .o
.cxx purge rm .o .dylib .cxx .pm
9Compiling and Linking C Example
SWIG example make file for Linux
all swig -c -perl example.i g -c
example.cpp example_wrap.cxx \
/usr/bin/perl -MExtUtilsEmbed -e ccopts g
-shared example.o example_wrap.o -L /usr/lib/ \
-lperl -o example.so clean rm
.o .cxx purge rm .o .so .cxx .pm
10Resulting C Library
- Differs with platform and operating system
- On Mac OS X a .dylib library is created
- On Unix Systems a shared (.so) library is
created - C library needs to be in same location as Perl
wrapper.
11Simple Example
/ Example.h / include ltvectorgt include
ltstringgt define PGSd_EOS_AM 2222
define PGSd_EOS_PM 3333 double
average(stdvectorltintgt v) stdvectorltdoublegt
half(const stdvectorltdoublegt v) stdstring
TestMod(const stdstring s)
12Simple Example (Cont)
// // example.cpp // include ltalgorithmgt includ
e ltfunctionalgt include ltnumericgt include
"example.h" using namespace std double
average(vectorltintgt v) return
(accumulate(v.begin(), v.end(),
0.0))/v.size() vectorltdoublegt half(const
vectorltdoublegt v) vectorltdoublegt
w(v) for( unsigned long i 0 i lt
w.size() i) wi / 2.0
return w stdstring TestMod(const
stdstring s) return string("TestOutput ")
s
13!/usr/bin/perl TestExample.pl use
strict use example my _at_intV (0..3) my _at_dblV
(0.0, 1.5, 1.0, 1.5) print "Integer Array
Values " map print "_ ," _at_intV print
"\nAverage ", exampleaverage(\_at_intV),
"\n" print "\nTry passing in an array of
doubles \n" eval "Average ",
exampleaverage(\_at_dblV), "\n" print "\tError
encountered _at_\n" if (_at_) print "Double Array
Values " map print "_ ," _at_dblV my ref
examplehalf(\_at_dblV) print "\nHalved Values
" map print "_ ," _at_ref print
"\n\n" my str "Hello World!\n" print
exampleTestMod(str) print "\nConstant
PGSd_EOS_AM ", examplePGSd_EOS_AM,
"\n" print "Constant PGSd_EOS_PM ",
examplePGSd_EOS_PM, "\n\n"
14TestExample.pls Output
Integer Array Values 0 ,1 ,2 ,3 , Average
1.5 Try passing in an array of doubles Error
encountered RuntimeError Type error in argument
1 of average. Expected an array of int Double
Array Values 0 ,1.5 ,1 ,1.5 , Halved Values 0
,0.75 ,0.5 ,0.75 , TestOutput Hello
World! Constant PGSd_EOS_AM 2222 Constant
PGSd_EOS_PM 3333
15Suggestions
- Use built-in or STL types arguments wherever
possible - Otherwise use custom built C data classes
consisting of above types - Link C code as shared objects if possible
- Place exception handling first in interface file
- Use SWIG_exception_fail
16References
- http//www.swig.org
- http//home.pacbell.net/ouster/scripting.html
- /CERES/instrument/home/bmagill/ComputerLanguages/P
erl/SWIG/SWIG_C/ - /CERES/instrument/home/bmagill/SolarAngle/Configur
ed/src/