C呼叫java例子
阿新 • • 發佈:2019-01-10
實驗程式碼已打包,下載地址。
實現原理:使用JNI提供的介面來反射得到Java方法,進行呼叫。jni.h在JDK裡(jdk1.8.0_121/include/)。
(通過JNI可以實現java呼叫C,也可以實現C呼叫java)
HelloWorld.java:
public class HelloWorld{ public static void main(String[] args){ System.out.println("Hello, World"); } public static int square(int input){ int output = input * input; return output; } public static int power(int input, int exponent){ int output,i; output=1; for(i=0;i<exponent;i++){ output *= input; } return output; } }
hello_world.c:
#include<stdio.h> #include<jni.h> JNIEnv* create_vm(JavaVM **jvm) { JNIEnv* env; JavaVMInitArgs args; JavaVMOption options; args.version = JNI_VERSION_1_6; args.nOptions = 1; options.optionString ="-Djava.class.path=./"; args.options = &options; args.ignoreUnrecognized = 0; int rv; rv = JNI_CreateJavaVM(jvm,(void**)&env, &args); if (rv < 0 || !env) printf("Unable to Launch JVM%d\n",rv); else printf("Launched JVM! :)\n"); return env; } void invoke_class(JNIEnv* env) { jclass hello_world_class; jmethodID main_method; jmethodID square_method; jmethodID power_method; jint number=20; jint exponent=3; hello_world_class =(*env)->FindClass(env, "HelloWorld"); main_method =(*env)->GetStaticMethodID(env, hello_world_class, "main","([Ljava/lang/String;)V"); square_method =(*env)->GetStaticMethodID(env, hello_world_class, "square","(I)I"); power_method =(*env)->GetStaticMethodID(env, hello_world_class, "power","(II)I"); (*env)->CallStaticVoidMethod(env,hello_world_class, main_method, NULL); printf("%d squared is %d\n",number, (*env)->CallStaticIntMethod(env,hello_world_class, square_method, number)); printf("%d raised to the %d power is%d\n", number, exponent, (*env)->CallStaticIntMethod(env,hello_world_class, power_method, number, exponent)); } int main(int argc,char **argv) { JavaVM *jvm; JNIEnv *env; env = create_vm(&jvm); if(env == NULL) return 1; invoke_class(env); return 0; }
# 編譯java
javac HelloWorld.java
# 編譯C
gcc -D__int64="long long" -Ic:/java/jdk1.8.0_121/include/ -Ic:/java/jdk1.8.0_121/include/win32 -ohello_world hello_world.c -L c:/java/jdk1.8.0_121/jre/bin/server -ljvm
要點:
a) 使用64位的JDK需要新增-D__int64="longlong"
b) 通過-I引數指定jni.h、jni_md.h的路徑。
c) 通過-L指定jvm.dll的路徑。
這3個檔案都在JDK資料夾裡面,可以通過搜尋找到具體的路徑。
#執行程式
hello_world
如果報找不到jvm.dll的錯,把jvm.dll(路徑:jdk1.8.0_121\jre\bin\server)註冊到系統。
可以寫Makefile一步到位,Makefile:
all: run
HelloWorld.class: HelloWorld.java
javac HelloWorld.java
hello_world: hello_world.c
gcc -D__int64="long long" -Ic:/java/jdk1.8.0_121/include/-Ic:/java/jdk1.8.0_121/include/win32 -o hello_world hello_world.c -Lc:/java/jdk1.8.0_121/jre/bin/server -ljvm
run: HelloWorld.class hello_world
./hello_world
clean:
rm -f HelloWorld.class hello_world
編譯和執行:
>make
輸出結果:
javac HelloWorld.java
gcc -Ic:/java/jdk1.8.0_121/include/ -Ic:/java/jdk1.8.0_121/include/win32 -ohello_world hello_world.c -L c:/java/jdk1.8.0_121/jre/bin/server -ljvm
./hello_world
Launched JVM! :)
Hello, World
20 squared is 400
20 raised to the 3power is 8000