本博文要做两件事
1:怎样将c文件编译成lib*.so
2:java同c语言文件如何传递返回数据类型
现在开始搞起:
- 1:怎样将c文件编译成lib*.so
Linux下编译共享库时,必须加上-fPIC参数,否则在链接时会有错误提示。故而我们的编译就变成了
gcc -fPIC -shared -o libnative.so native.c
但是呢有提示说找不到jni.h 的路径,那么咱们给gcc编译制定路径呗
gcc -I/usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ -fPIC -shared -o libnative.so native.c
呶完美。我们有了c语言的动态库。我们运行java JNIDemo的时候仍旧报错。no native in java.library.path这是因为我们没有给制定库的路径。
export LD_LIBRARY_PATH=.
加上这一个就可以了。
OK解决掉第一个见过就会,看过就忘的知识点。下面开始真正恶心人的地方。
- 2 java同c语言文件如何传递返回数据类型
从实用的角度,我准备在这部分投机取巧。我就记住传递字符串,传递数组,传递基本类型数据。这三类。然后用到了我就来这儿扒代码。本着这个思想幸福的贴代码吧!!
- 传递基本类型数据(直接使用,直接返回)
jint c_hello(JNIEnv *env, jobject cls, jint m)
{
printf("Hello, world! val = %d\n", m);
return 100;
}
static const JNINativeMethod methods[] = {
{"hello", "(I)I", (void *)c_hello},
};
贴关键部分。
2. 传递为字符串
jstring JNICALL c_hello(JNIEnv *env, jobject cls, jstring str)
{
//printf("this is c : %s\n", str);
//return "return from C";
const jbyte *cstr;
cstr = (*env)->GetStringUTFChars(env, str, NULL);
if (cstr == NULL) {
return NULL; /* OutOfMemoryError already thrown */
}
printf("Get string from java :%s\n", cstr);
(*env)->ReleaseStringUTFChars(env, str, cstr);
return (*env)->NewStringUTF(env, "return from c");
}
static const JNINativeMethod methods[] = {
{"hello", "(Ljava/lang/String;)Ljava/lang/String;", (void *)c_hello},
};
3.传递的数组类型
jint c_hello(JNIEnv *env, jobject cls, jintArray arr)
{
jint *carr;
jint i, sum = 0;
carr = (*env)->GetIntArrayElements(env, arr, NULL);
if (carr == NULL) {
return 0; /* exception occurred */
}
for (i=0; i< (*env)->GetArrayLength(env, arr); i++) {
sum += carr[i];
}
(*env)->ReleaseIntArrayElements(env, arr, carr, 0);
return sum;
}
static const JNINativeMethod methods[] = {
{"hello", "([I)I", (void *)c_hello},
};
阔以了,万事大吉。
接下来的博客安排,先不去写异常 还有 c调用java部分。我记不住,什么时候用到的时候我再补充这个系列。接下来进行反射和内部类的知识补充。