1、 打开新立得包管理器,搜索JDK,选择openjdk-6-jdk安装;
2、 打开Ubuntu软件中心,搜索Eclipse,选择Eclipse集成开发环境,安装;
3、 打开Eclipse,File-->New-->Java Project-->Project name:TestJavaJNI-->next-->Finish,选中TestJavaJNI,点击右键-->new-->Class,Name:TestJNI-->Finish,编写Java类;
public class TestJNI
{
public native int add(int a, int b);
public native String upperCase(String str);
static
{
System.loadLibrary("JniDll");
}
public static void main(String[] args)
{
TestJNI test = new TestJNI();
int a=10, b=20, result;
result = test.add(a, b);
System.out.println("两者的和为: " + result);
String str1, str2;
str1 = "abcDEFhijk";
str2 = test.upperCase(str1);
System.out.println(str2);
}
}
4、 打开终端,进入到TestJNI.java所在目录下,执行 javac TestJNI.java命令,编译完成后生成TestJNI.class文件;
5、 执行Javah TestJNI命令,生成TestJNI.h头文件;
6、 打开Code::Blocks,file-->new-->Projects-->选中Shared library,-->Go-->next-->c++,Next-->Project title:JniDll-->next-->Finish,生成一个main.cpp文件;
#include "TestJNI.h"
#include <iostream>
#include <cstring>
#include <stdlib.h>
using namespace std;
extern "C"
{
char* jstringToNative(JNIEnv *env, jstring jstr)
{
if (env->ExceptionCheck() == JNI_TRUE || jstr == NULL)
{
env->ExceptionDescribe();
env->ExceptionClear();
printf("jstringToNative函数转换时,传入的参数jstr为空");
return NULL;
}
jbyteArray bytes = 0;
jthrowable exc;
char *result = 0;
if (env->EnsureLocalCapacity(2) < 0)
{
return 0; /* out of memory error */
}
jclass jcls_str = env->FindClass("java/lang/String");
jmethodID MID_String_getBytes = env->GetMethodID(jcls_str, "getBytes", "()[B");
bytes = (jbyteArray)env->CallObjectMethod(jstr, MID_String_getBytes);
exc = env->ExceptionOccurred();
if (!exc)
{
jint len = env->GetArrayLength( bytes);
result = (char *)malloc(len + 1);
if (result == 0)
{
//JNU_ThrowByName(env, "java/lang/OutOfMemoryError", 0);
env->DeleteLocalRef(bytes);
return 0;
}
env->GetByteArrayRegion(bytes, 0, len, (jbyte *)result);
result[len] = 0; /* NULL-terminate */
}
else
{
env->DeleteLocalRef(exc);
}
env->DeleteLocalRef(bytes);
return (char*)result;
}
jstring nativeTojstring( JNIEnv* env,const char* str )
{
jclass strClass = env->FindClass( "Ljava/lang/String;");
jmethodID ctorID = env->GetMethodID( strClass, "<init>",
"([BLjava/lang/String;)V");
if (env->ExceptionCheck() == JNI_TRUE || str == NULL)
{
env->ExceptionDescribe();
env->ExceptionClear();
printf("nativeTojstring函数转换时,str为空\n");
return NULL;
}
jbyteArray bytes = env->NewByteArray( strlen(str));
//如果str为空则抛出异常给jvm
env->SetByteArrayRegion( bytes, 0, strlen(str), (jbyte*)str);
//jstring encoding = env->NewStringUTF( "GBK");
jstring encoding = env->NewStringUTF( "UTF8");
jstring strRtn = (jstring)env->NewObject( strClass, ctorID, bytes,
encoding);
//释放str内存
// free(str);
return strRtn;
}
char* strupr(char *str)
{
char *p = str;
while (*p != '\0')
{
if (*p >= 'a' && *p <= 'z')
{
*p -= 0x20;
}
p++;
}
return str;
}
JNIEXPORT jint JNICALL Java_TestJNI_add(JNIEnv *env, jobject, jint a, jint b)
{
int result = (int)(a + b);
return (jint)result;
}
JNIEXPORT jstring JNICALL Java_TestJNI_upperCase(JNIEnv *env, jobject, jstring str)
{
string strUpper;
strUpper = (string)jstringToNative(env,str);
strUpper = (string)strupr((char *)strUpper.c_str());
jstring strResult = nativeTojstring(env, strUpper.c_str());
return strResult;
}
}
7、 将TestJNI.h头文件复制到main.cpp目录,并添加到工程中,分别在Release和Debug下,Projectàbuild optionsàSearch directoriesàCompileràAdd:
../../../../../usr/lib/jvm/java-6-openjdk/include/linux
../../../../../usr/lib/jvm/java-6-openjdk/include
Project-->build options-->compiler settings-->Other options加入-fPIC;编译生成libJniDll.so;
8、 使用sudo cp命令将libJniDll.so(Release或Debug)拷贝到/usr/lib目录下;
9、 在Eclipce中运行TestJNI.java或在终端运行java TestJNI,运行结果:
两者的和为: 30
ABCDEFHIJK
参考文献:
1、 http://blog.sina.com.cn/s/blog_6a6b58ce0100oiip.html
2、 http://blog.csdn.net/lee353086/article/details/6160576