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,运行