Java代码
InvocationApiTest.java
public class InvocationApiTest{
public static void main(String[) args){
System.out.println(args[O]);
}
}
编译 InvocationApiTest.java 生成 InvocationApiTest.class
C代码
invocationApi.c
#include <jni.h>
int main(){
JNIEnv *env;
JavaVM *vm;
JavaVMInitArgs vm_args;
JavaVMOption options[1];
jint res;
jclass cls;
jmethodID mid;
jstring jstr;
jclass stringClass;
jobjectArray args;
//1.生成 Java 虚拟机选项
options[0].optionString = "-Djava.class.path=.";
vm_args.version = 0x00010002;
vm_args.options = options;
vm_args.nOptions = 1;
vm_args.ignoreUnrecognized = JNI_TRUE;
//2.生成 Java 虚拟机
res = JNI_CreateJavaVM(&vm, (void**)&env, &vm_args);
//3.查找并加载类
cls = (*env)->FindClass(env, "InvocationApiTest");
//4.获取 main() 方法的 ID
mid = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V");
//5.生成字符串对象,用作 main() 方法的参数
jstr = (*env)->NewStringUTF(env, "Hello Invocation API!!");
stringClass = (*env)->FindClass(env, "java/lang/String");
args = (*env)->NewObjectArray(env, 1, stringClass, jstr);
//6.调用 main() 方法
(*env)->CallStaticVoidMethod(env, cls, mid, args);
//7.销毁 Java 虚拟机
(*vm)->DestroyJavaVM(vm);
}
编译C代码(Ubuntu)
gcc -I /usr/lib/jvm/java-7-openjdk-amd64/include -I /usr/lib/jvm/java-7-openjdk-amd64/include/linux -L /usr/lib/jvm/java-7-openjdk-amd64/jre/lib/amd64/server/ invocationApi.c -ljvm
注:-I 参数添加 jni.h 和 jni_md.h 头文件路径,-L 参数添加 libjvm.so 共享库路径,-ljvm 参数指定要链接的jvm库。
编译后生成 a.out 可执行文件
运行
运行之前需要将 libjvm.so 的路径添加到 /etc/ld.so.conf 文件下
vim /etc/ld.so.conf
# 使修改生效
/sbin/ldconfig
运行 a.out
./a.out
输出:
成功!
参考资料:
《Android框架揭秘》