Para criar bibliotecas em código nativo será necessário instalar o JDK e o gcc. Seria bom também instalar o gcc-java caso queira usar o gcj para compilar o código Java.
Neste tópico vou mostrar um simples exemplo que utiliza o JNI.
Vamos criar um programa Java que vai declarar a função chamada getSoma, que receberá dois parâmetros e resultará a soma dos dois em forma de string.
Veja o código:
exemplo1.java:
public class exemplo1{
//declaração da função que será implementada pelo código c++
public native String getSoma(int a, int b);
static{
System.loadLibrary("exemplo1"); //carrega a biblioteca libexemplo1.so
}
public static void main(String args[]){
exemplo1 app = new exemplo1();
String retorno = app.getSoma(2,3);
System.out.println("O resultado de 2+3 é "+retorno);
}
}
Para compilar:
javac exemplo1.java
Agora devemos gerar o arquivo exemplo1.h usando o aplicativo javah:
javah -jni exemplo1
Será gerado o arquivo de cabeçalho exemplo1.h com a declaração da função.
Veja o arquivo abaixo:
exemplo1.h:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class exemplo1 */
#ifndef _Included_exemplo1
#define _Included_exemplo1
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: exemplo1
* Method: getSoma
* Signature: (II)Ljava/lang/String;
*/
//Abaixo está a declaração da função que vamos ter que implementar no arquivo exemplo1.cpp
JNIEXPORT jstring JNICALL Java_exemplo1_getSoma(JNIEnv *, jobject, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
Observe que o javah declarou a função com o padrão JNI. Os parâmetros int foram substituídos por jint e String substituído por jstring.
Agora devemos criar o arquivo exemplo1.cpp implementando esta função.
Vamos lá:
exemplo1.cpp:
#include "exemplo1.h"
#include <iostream>
#include <sstream>
using std::string;
using std::ostringstream;
string intToStr(int numero); //função para facilitar a manipulação das informações
/*observe que acrescentei as variáveis env, a, b na implementação da função.
O ponteiro "env" contém funções úteis para conversão entre tipos nativos e tipos primitivos da linguagem C/C++.
As variáveis a e b serão usadas na função
*/
JNIEXPORT jstring JNICALL Java_exemplo1_getSoma(JNIEnv *env, jobject, jint a, jint b){
jstring resultado; //criando a variável retorno
string sresultado; //criando a variável string para facilitar o desenvolvimento.
sresultado = intToStr(a+b);
//A função env->NewStringUTF recebe um char* e retorna um jstring.
//Já sresultado.c_str() retorna um char* que será convertido em jstring.
resultado = env->NewStringUTF(sresultado.c_str());
return resultado; //retorno para o java.
}
//função criada para converter um int em string.
string intToStr(int numero){
std::ostringstream svalor;
svalor << numero;
return svalor.str();
}
Agora basta compilar o arquivo exemplo1.cpp:
g++ -fPIC -shared -o libexemplo1.so exemplo1.cpp
Este comando vai gerar o arquivo libexemplo1.so. Copie este arquivo para a pasta /usr/lib64 ou /usr/lib dependendo da sua distribuição
Linux.
Para testar basta executar o programa exemplo1.class.
java exemplo1
Você deve obter o resultado:
O resultado de 2+3 é 5.