环境
jni是java自带的功能,在jdk目录下有,c语言在调用时需要配置环境参数
echo "export CFLAGS=\"-I\$JAVA_HOME/include/ -I\$JAVA_HOME/include/linux\"" >> ~/.bashrc # 头文件加载
echo "export LDFLAGS=\"-L\$JAVA_HOME/jre/lib/amd64/jli/ -ljli -L\$JAVA_HOME/jre/lib/amd64/server -ljvm\"" >> ~/.bashrc # 动态库的加载包括 libjli.so(-ljli就是指这个),libjvm.so(-ljvm)
echo "export LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:\$JAVA_HOME/lib/amd64/jli:\$JAVA_HOME/jre/lib/amd64/server" >> ~/.bashrc # c语言需要的环境边量
source ~/.bashrc # 让上述设定生效
目录总览
./
|-- demo
| `-- ToSay.java
`-- main.c
# ToSay是被调用的java文件
# main.c是调用者
案例
main.c
#include<jni.h>
#include<stdlib.h>
int main()
{
JavaVM *jvm;
JNIEnv *env;
jclass cls;
jstring jstr;
jmethodID mth;
JavaVMOption options[2];
JavaVMInitArgs jvm_args;
options[0].optionString = "-Djava.class.path=."; // java 文件路径
options[1].optionString = "-Djava.library.path=."; //设置本地库(.jar,这里没有),好像上面的也可以设.jar的路径,具体功能我不清楚,设计文档上面是说这个是本地库
jvm_args.version = JNI_VERSION_1_8;
jvm_args.nOptions = 1;
jvm_args.options = options;
jvm_args.ignoreUnrecognized = JNI_TRUE;
jint res = JNI_CreateJavaVM(&jvm, (void **)&env, &jvm_args);
if (res != JNI_OK) {
printf("Failed to create Java VM\n");
return 1;
}
cls = (*env)->FindClass(env, "demo/ToSay");
if (cls == NULL) {
printf("Failed to find ToSay class\n");
return 1;
}
// 最后一个参数解释: (传入参数)返回值
/*
Java类型 符号
Boolean Z
Byte B
Char C
Short S
Integer I
Long L
Float F
Double D
Void V
Object对象 L开头,包名/类名,”;”结尾,$标识嵌套类
数组 [内部类型
*/
// 所以这里是(String)void
mth = (*env)->GetStaticMethodID(env, cls, "SayHello", "(Ljava/lang/String;)V");
if (mth == NULL) {
printf("Failed to find Sayhello functionn\n");
return 1;
}
char words[]="Today is a happy day!";
jstring arg = (*env)->NewStringUTF(env, words);
(*env)->CallStaticVoidMethod(env, cls, mth, arg);
(*env)->DeleteLocalRef(env, arg);
(*env)->DeleteLocalRef(env, cls);
(*jvm)->DestroyJavaVM(jvm);
return 0;
}
ToSay.java
package demo;
public class ToSay{
public static void SayHello(String words)
{
System.out.println("I say "+words);
}
}
运行
# 编译java
javac demo/*.java # 如果有多个.jar包则编译用 javac -cp 1.jar:2.jar:...: demo/*.java
# 编译c
gcc -g main.c $CFLAGS $LDFLAGS -o hello
# 运行c
./hello
:I say Today is a happy day! # 如果成功,就会显示这个