Monday 16 September 2013

Groovy and C++ through JNA

Last week I attended a talk at Kaleidos about integrating/extending Python with C++ (Great talk by the way).

Because there's a kind of healthy competition inside Kaleidos.net I'm thinking about coding some C++ again (I probably did my last line of c++ like 10 years ago but WTF let's do this!!! :P)

When talking about integrating C++ with the JVM (as far as I know) there's only two choices JNI and JNA.

I googled for a while and I got to the point where I decided to go for JNA instead of JNI. The reason was the JNI looked more cumbersome than JNA.

First step: Create your C++ code:


Well the first step was to create my C++ code. That's easier said than done. Like I said my C++ is more than rusty. Anyway I came up with the following sample code, don't take it too seriously:

//Algorithms.h

class Algorithms {         
   
     public:
       int getMax(int*,int);
 
 };

//Algorithms.cpp

#include "Algorithms.h"    
   
extern "C" int getMax(int* numbers,int numbersLength) {
   
   Algorithms instance;     
   return instance.getMax(numbers,numbersLength);
 
}
  
int Algorithms::getMax(int* numbers,int numbersLength) {
  
   int max = 0;
  
   for (int i = 0; i < numbersLength ; i++) { 
     int next = numbers[i];
     if (next > max){
       max = next; 
     }
   }
  
   return max;
  
}

The most important detail here is to externalize the code with the 'extern "C"' part.

There's a useful tool called objdump you can use to inspect the resulting library in order to find out which functions are accesible from outside.

By the way, the c++ project is compiled using Gradle cpp plugin;)

Second step: Invoke your code!


Then I wrote the following code in the groovy console:

@Grab( 'net.java.dev.jna:jna:3.4.0' )
import com.sun.jna.Library
import com.sun.jna.Native
 
System.setProperty("jna.library.path","/pathToTheLibraryDir")
 
interface Algorithms extends Library {
    public int getMax(int[] numbers,int numbersLength);
}

def instance = Native.loadLibrary( 'cpp',Algorithms)
def numbers = [1,2,3,4] as int[]
instance.getMax(numbers,numbers.size())


Thinks to take into account.
  • The jna property is one of the three ways of telling JNA where the C++ library is. You can check the other two at the Github JNA page.
  • You can invoke the script without specifying the location of the library if you executed groovyConsole in the same dir.

Thanks to the people of MadridJUG mailing list. They saved me a lot of time.

References



1 comment:

  1. I have read your blog and i got a very useful and knowledgeable information from your blog.If you are looking for best Oracle financials online training is one of the leading Online Training institute in Hyderabad.
    Oracle fusion financials training

    ReplyDelete