1 / 16

Wrapping C++ with Perl

Wrapping C++ with Perl. Brian Magill March 2009. SWIG (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

kalea
Télécharger la présentation

Wrapping C++ with Perl

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Wrapping C++ with Perl Brian Magill March 2009

  2. SWIG (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

  3. Motivation • 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

  4. File 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)

  5. SWIG 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

  6. Example Interface File %include "exception.i" %exception { try { $action } catch (const std::exception &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) std::vector<int>; %template(DoubleVector) std::vector<double>; %include "example.h"

  7. Running the SWIG Command • swig –c++ -perl5 example.i • Produces: • example_wrap.cxx … C++ Wrapper • example.pm … Perl Wrapper

  8. Compiling and Linking C++ Example # # Make file: MacIntosh version # all: swig -c++ -perl5 example.i g++ -c example.cpp example_wrap.cxx \ `/usr/bin/perl -MExtUtils::Embed -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

  9. Compiling 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 -MExtUtils::Embed -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

  10. Resulting 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.

  11. Simple Example /* Example.h */ #include <vector> #include <string> #define PGSd_EOS_AM 2222 #define PGSd_EOS_PM 3333 double average(std::vector<int> v); std::vector<double> half(const std::vector<double> & v); std::string TestMod(const std::string &s);

  12. Simple Example (Con’t) // // example.cpp // #include <algorithm> #include <functional> #include <numeric> #include "example.h" using namespace std; double average(vector<int> v) { return (accumulate(v.begin(), v.end(), 0.0))/v.size();} vector<double> half(const vector<double> & v) { vector<double> w(v); for( unsigned long i = 0; i < w.size(); i++) w[i] /= 2.0; return w; } std::string TestMod(const std::string &s) {return string("TestOutput: ") + s;}

  13. #!/usr/bin/perl # # TestExample.pl # use strict; use example; my @intV = (0..3); my @dblV = (0.0, 1.5, 1.0, 1.5); print "Integer Array Values: "; map { print "$_ ,"; } @intV; print "\nAverage = ", example::average(\@intV), "\n"; print "\nTry passing in an array of doubles: \n"; eval {"Average = ", example::average(\@dblV), "\n"; }; print "\tError encountered: $@\n" if ($@); # print "Double Array Values: "; map { print "$_ ,"; } @dblV; my $ref = example::half(\@dblV); print "\nHalved Values: "; map { print "$_ ,"; } @$ref; print "\n\n"; # my $str = "Hello World!\n"; print example::TestMod($str); print "\nConstant PGSd_EOS_AM = ", $example::PGSd_EOS_AM, "\n"; print "Constant PGSd_EOS_PM = ", $example::PGSd_EOS_PM, "\n\n";

  14. TestExample.pl’s 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

  15. Suggestions • 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

  16. References • http://www.swig.org • http://home.pacbell.net/ouster/scripting.html • /CERES/instrument/home/bmagill/ComputerLanguages/Perl/SWIG/SWIG_C++/ • /CERES/instrument/home/bmagill/SolarAngle/Configured/src/

More Related