Ubuntu下,Java中利用JNI调用codeblocks c++生成的动态库的使用步骤
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
總結
以上是生活随笔為你收集整理的Ubuntu下,Java中利用JNI调用codeblocks c++生成的动态库的使用步骤的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: windows7下,Java中利用JNI
- 下一篇: 运动目标检测__光流法