Ubuntu下,Java中利用JNI调用codeblocks c++生成的动态库的使用步骤

1、  打开新立得包管理器,搜索JDK,选择openjdk-6-jdk安装;

2、  打开Ubuntu软件中心,搜索Eclipse,选择Eclipse集成开发环境,安装;

3、  打开EclipseFile-->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::Blocksfile-->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目录,并添加到工程中,分别在ReleaseDebug下,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(ReleaseDebug)拷贝到/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

你可能感兴趣的:(Ubuntu下,Java中利用JNI调用codeblocks c++生成的动态库的使用步骤)