C语言调用java也是经过JNI实现的,Linux平台也就是引入libjvm.so动态连接库就能够。首先须要编写java类java
public class Sample { public static void test2() { System.out.println("java打印的helloword"); } }
这是很是简单的一个java类,里面就只有一个java方法。等下咱们就要经过C来调用这个方法。jvm只认识class,首先得编译它,java Sample.java。在当前目录获得一个Sample.class的文件。这个文件等下会被咱们的C程序加载。linux
而后编写C代码。apache
#include <jni.h>//引入jni的头文件,下面加载类和调用类的方法都是经过jni里面的函数实现的 #include <string.h> int main() { JavaVMOption options[1]; JNIEnv *env; JavaVM *jvm; JavaVMInitArgs vm_args; long status; jclass cls; jmethodID mid; jint square; jboolean not; options[0].optionString = "-Djava.class.path=."; //设置classpath memset(&vm_args, 0, sizeof(vm_args)); vm_args.version = JNI_VERSION_1_2; vm_args.nOptions = 1; vm_args.options = options; status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); if (status != JNI_ERR) { //cls = (*env)->FindClass(env, "java/lang/Object"); cls=(*env)->FindClass(env,"Sample");//经过FindClass函数找到这个类,这里须要添加类的描述符合,若是是Object就应该是java/lang/Object printf("find the class\n"); if(cls !=0) { //mid = (*env)->GetStaticMethodID(env, cls, "main", "(I)I"); mid=(*env)->GetStaticMethodID(env,cls,"main","([Ljava/lang/String;)V");//经过函数找到方法,这里面应该是方法的描述符。 printf("find the method\n"); if(mid !=0) { printf("exec method\n"); square = (*env)->CallStaticIntMethod(env, cls, mid, NULL); //执行方法 printf("Result of intMethod: %d\n", square); } mid = (*env)->GetStaticMethodID(env, cls, "booleanMethod", "(Z)Z"); if(mid !=0) { not = (*env)->CallStaticBooleanMethod(env, cls, mid, 1); printf("Result of booleanMethod: %d\n", not); } } else{ printf("not found\n"); } (*jvm)->DestroyJavaVM(jvm); return 0; } else return -1; }
,若是直接gcc 是会报错的,由于jni头文件不在系统的头文件里面。并且动态连接库也不在系统默认的库里面。因此编写一个Makefile:bash
compile: gcc calljvm.c -I $JAVA_HOME/include/ -I $JAVA_HOME/include/linux/ -L$JAVA_HOME/jre/lib/amd64/server/ -ljvm -o calljvm
执行make,顺利应该编译经过,可是执行是会报错的。由于libjvm.so不在/usr/lib 里面。因此得把jvm的库加到系统库路径里面jvm
export LD_LIBRARY_PATH=$JAVA_HOME/jre/lib/amd64/:$JAVA_HOME/jre/lib/amd64/servr
系统默认会在/usr/lib里面寻找动态连接库,若是有LD_LIBRARY_PATH以后会优先在LD_LIBRARY_PATH指定路径找,若是找不到再去/usr/lib。函数
再次编译连接运行,成功打印!spa