java通過JNI向C/C++傳遞基本數據類型比較簡單,但基本數據類型很難滿足應用程序開發的需要,心想要是能傳遞一個數據結構/類就好了。於是通過下面例子實驗了通過JNI傳遞數據結構/類也是OK的
1,定義一個用於測試的數據類(很簡單,沒有成員方法)
package com.rain.test;
public class testclass {
public int iValue;
public String strValue;
}
2,java主程序
package com.rain.test;
public class jniproject {
public native String hello(testclass value);
static
{
System.loadLibrary("jniproject");
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
testclass c = new testclass();
c.iValue = 100;
c.strValue = new String("HelloWorld");
jniproject prj = new jniproject();
String strResult = prj.hello(c);
System.out.print(strResult);
}
}
3,工程中建立jni目錄,並利用javah編譯出c頭文件
javah -classpath bin -d jni com.rain.test.jniproject
4,新建jniproject.c文件實現native方法
#include "com_rain_test_jniproject.h"
#include <jni.h>
typedef struct
{
int iValue;
char* pStrValue;
}TestClass;
jstring Java_com_rain_test_jniproject_hello(JNIEnv* pEnv, jobject obj, jobject arg)
{
jclass jcarg = (*pEnv)->GetObjectClass(pEnv, arg);
TestClass input;
jfieldID iid = (*pEnv)->GetFieldID(pEnv, jcarg, "iValue", "I");
input.iValue = (*pEnv)->GetIntField(pEnv, arg, iid);
jfieldID strid = (*pEnv)->GetFieldID(pEnv, jcarg, "strValue", "Ljava/lang/String;");
jstring strValue = (*pEnv)->GetObjectField(pEnv, arg, strid);
jsize strLen = (*pEnv)->GetStringUTFLength(pEnv, strValue);
const char* pStrValue = (*pEnv)->GetStringUTFChars(pEnv, strValue, NULL);
input.pStrValue = malloc(strLen + 1);
strcpy(input.pStrValue, pStrValue);
(*pEnv)->ReleaseStringUTFChars(pEnv, strValue, pStrValue);
char buff[256] = {0};
snprintf(buff, 255, "%d + %s", input.iValue, input.pStrValue);
free(input.pStrValue);
return (*pEnv)->NewStringUTF(pEnv, buff);
}
5,編譯動態庫
$ gcc -c -fPIC -I$JAVA_HOME/include -I$JAVA_HOME/include/linux jniproject.c
$ gcc -shared -fPIC -o libjniproject.so jniproject.o
6,爲了使java能夠找到so文件,避免程序運行時出現“java.library.path”相關的錯誤,需在eclipse中設置
select project, right click->properties, "java build path", "libraries" tab, select a jar, expand it, select "Native library location", click "edit...", folder chooser dialog will appear
7,運行