C語言調用java

    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

相關文章
相關標籤/搜索