在这篇博文中,博主将会实现一个Java发送数据到C的例子,数据将由C输出
功能如下:
1、从Java传递字符串到C
2、在C下输出字符串
环境:Ubuntu12.04
java-6-openjdk
vim
gcc
废话少说
步骤一、先打开Ubuntu的终端编写一个Java类
博主为了方便直接复制了上一篇文章的文件,更改了一个名字
public class PrintHelloWorld{
public native void helloWorld(String str);
public static void main(String[] args){
PrintHelloWorld t =new PrintHelloWorld();
t.helloWorld("Hello World");
}
static{//动态库名字为 libprinthelloworld_2.so
System.loadLibrary("printhelloworld_2");
}
}
我们要传过去的数据是"Hello World"
在这里说一下.so文件的命名规则,假设你在java中static{}块中System.loadLibrary(“ABC”),那么你之后生成的.so文件名就应该是lib+ABC+.so
步骤二、编译java文件,生成头文件
javac PrintHelloWorld.java
javah PrintHelloWorld
这时候我们可以看到当前目录下有三个文件
PrintHelloWorld.java
PrintHelloWorld.class
PrintHelloWorld.h
步骤三、根据PrintHelloWorld.h文件,编写PrintHelloWorld.c文件
博主懒,直接把PrintHelloWorld.h复制了一份
头文件是这样的
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class PrintHelloWorld */
#ifndef _Included_PrintHelloWorld
#define _Included_PrintHelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: PrintHelloWorld
* Method: helloWorld
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_PrintHelloWorld_helloWorld
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
看这个头文件和上一篇文章的HelloWorld.h可以发现
在Java_PrintHelloWorld_helloWorld的方法中,多了一个参数jstring,这个jstring就是你从java传过来的String对象
但是你是不能在C中直接使用的,所以要把它转化为char类型
步骤四、在PrintHelloWorld.c文件中把jstring转化为char,并输出
博主把不要的信息删掉了
#include <stdio.h>
#include "PrintHelloWorld.h"
JNIEXPORT void JNICALL Java_PrintHelloWorld_helloWorld
(JNIEnv *env, jobject obj, jstring str)
{
const char* cstr=(*env)->GetStringUTFChars(env,str,0);
printf("%s \n",cstr);
}
由于上一篇文章中没有提到,在这里,博主都说一下JNIEnv , jobject这两个东东,博主没学过C,不知道怎么称呼它们,JNIEnv封装了JNI的环境,
里面有很多函数。
比如:
jstring (JNICALL *NewString)
(JNIEnv *env, const jchar *unicode, jsize len);
你就可以通过
(*env)->NewString(env,unicode,len);
获得一个jstring对象,如果Java的一个native方法需要返回String对象
你就可以用return返回jstring对象给java
同理类的对象也是可以用这种方法创建的,具体大家可以查阅相关资料或者jni.h文件
步骤五、通过PrintHelloWorld.c文件生成libprinthelloworld.so文件,并且把so文件复制到/usr/lib中
具体方法,上一章已经提到
这个过程是需要权限的
可以用sudo su获得