GCJ::Cni::Examples

GCJ::Cni::Examples is a Perl module with examples of how to use GCJ's CNI interface to write Perl Modules in Java.
Download

GCJ::Cni::Examples Ranking & Summary

Advertisement

  • Rating:
  • License:
  • Perl Artistic License
  • Price:
  • FREE
  • Publisher Name:
  • GCJ::Cni::Examples team
  • Publisher web site:
  • http://search.cpan.org/~rusekd/GCJ-Cni-0.03/lib/GCJ/Examples.pod

GCJ::Cni::Examples Tags


GCJ::Cni::Examples Description

GCJ::Cni::Examples is a Perl module with examples of how to use GCJ's CNI interface to write Perl Modules in Java. GCJ::Cni::Examples is a Perl module with examples of how to use GCJ's CNI interface to write Perl Modules in Java.EXAMPLESWriting Treaded modules in JavaOne benefit of using GCJ is that it takes advantage of POSIX threading. This is nice since Perl's threading model is, shall we say, less than ideal. Now, you could theoretically write a module in C or C++ and and use the standard POSIX library to do your threaded work for you, however, why not take advantage of the nice Threading interface that Java provides to you by default. This may also come in handy if you have a massively threaded Java library that you'd like to call from Perl.For this example assume that I want to do matrix multiplication, albeit in a very crazy manner. Therefore, I will write a Java class, Matrix, and a method, multiply, which will take another matrix to perform the operation between. Here's the crazy part, for each cell in the resulting matrix I will spawn a new thread, as an internal class, and give it a row and a column from which they will derive the result. I know this is a little wierd but the point is that I'll be spawning a lot of new threads. To multiply two 10x10 matrices we will have to spawn 100 threads (one thread per cell in the resulting 10x10 matrix). Imagine doing this in Perl, then imagine doing it in Java; natively compiled Java. Much faster and a lot less headaches.The Java Interface/pseudocode is as follows: public class Matrix { public Matrix ( int numRows, int numCols ) { ...Constructor stuff... } public void set ( int row, int col, int val ) { ...set an element... } public int get ( int row, int col ) { ...get an element... } public Matrix multiply ( Matrix times ) { ...set it up... for ( int i = 0; i < rows; i++ ) { for ( int j = 0; j < times.getCols(); j++ ) { //GO NUTS!!!! ArrayMultiplier multiplier = new ArrayMultiplier(this, times, result, i, j); multiplier.start(); ...etc... } } ...wait for the threads to exit and return the new matrix... } public int getRows ( ) { ...get number of rows... } public int getCols ( ) { ...get number of columns... } public void print ( ) { ...print the matrix to stdout... } private class ArrayMultiplier extends Thread { public ArrayMultiplier ( Matrix a, Matrix b, Matrix result, int row, int col ) { ...Construct this bad boy... } public void run ( ) { int sum = 0; for ( int i = 0; i < a.getCols(); i++ ) { sum += (a.get(row, i) * b.get(i, col)); } result.set(row, col, sum); } } }Now, we want to call this class from Perl. My perferred manner is through SWIG so that's what we're going to use. However, you do not need to use SWIG, you can use whatever method you prefer when wrapping C++ classes. We begin by creating a C++ header file from our above class. This is done by using GCJ's gcjh utility. First we need to class compile Matrix.java gcj -C Matrix.javaThen we go ahead and create the header file: gcjh MatrixEasy enough. We can then extract the interface we want to have available in Perl from the generated header file and from it create a i file to be used as input to SWIG. I usually start by copying my header file to the same named file but with an i extension instead. I then remove all of the grimy C++ gruff, private methods and variables, slap a module directive on it and call it done. It won't always be this easy though. When you're done an interface file for the above class should look something like this: %module Matrix; typedef int jint; class Matrix { public: Matrix (jint, jint); virtual void set (jint, jint, jint); virtual jint get (jint, jint); virtual ::Matrix *multiply (::Matrix *); virtual jint getRows (); virtual jint getCols (); virtual void print (); };We then put SWIG to work and generate our C++ wrapper for Perl: swig -perl -c++ Matrix.iAfter the above command we now will see two new files in our current directory, Matrix.pm and Matrix_wrap.cxx; these correspond the module directive we gave in Matrix.i.At this point all we have left to do is compile, and use. gcj -c Matrix.java gcc -c -I -include Matrix.h Matrix_wrap.cxx gcc -shared -lgcj -lstdc++ Matrix.o Matrix_wrap.o -oMatrix.soA simple Perl file using this module might look something like: sub populate_matrix { my $matrix = shift; for ( my $i = 0; $i < $matrix->getRows(); $i++ ) { for ( my $j = 0; $j < $matrix->getCols(); $j++ ) { $matrix->set($i, $j, $i * $j); } } } use GCJ::Cni; use Matrix; GCJ::Cni::JvCreateJavaVM(undef); GCJ::Cni::JvAttachCurrentThread(undef, undef); my $matrix = new Matrix::Matrix(10, 10); populate_matrix($matrix); my $matrix2 = new Matrix::Matrix(10, 10); populate_matrix($matrix2); $matrix3 = $matrix->multiply($matrix2); $matrix3->print(); GCJ::Cni::JvDetachCurrentThread();I'll leave it up to the reader to write a Perl module that does the same thing, that is, spawns 100 threads. In my own personal fiddling I found that just spawning that many threads (never mind doing any kind of work) was over 3 time slower in Perl. In this situation we at least get to use our favorite language, Perl, and offload some of the heavy hitting to a language more suited for it.Where this really comes in handy is when you have an existing multi-threaded Java library that you would like to expose to Perl. You could theoretically natively compile various components of your library and then generate Perl bindings to access it. In this way, you get a little extra speed and efficiency as well as code reuse and binding.Requirements:· Perl Requirements: · Perl


GCJ::Cni::Examples Related Software