originals-tz
11/2/2019 - 2:30 AM

Java

#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <jni.h>
#include <iostream>

int main(int argc, char *argv[])
{
    //Java虚拟机
    JavaVM *jvm = NULL;

    //Jni运行环境
    JNIEnv *env = NULL;

    //虚拟机初始化参数
    JavaVMInitArgs jvm_args;

    //java虚拟机参数, 这里只使用classpath这一项,所以长度为1
    JavaVMOption opt[1];

    //设置初始化参数(classpath 为当前目录)
    opt[0].optionString = "-Djava.class.path=.";

    //初始化虚拟机初始化参数
    memset(&jvm_args, 0, sizeof(jvm_args));

    //设置jni环境版本
    jvm_args.version = JNI_VERSION_1_6;

    //参数的个数
    jvm_args.nOptions = 1;

    //虚拟机参数
    jvm_args.options = opt;

    //创建java虚拟机 返回0为启动成功,其他数值的意义在头文件中有定义
    long jvm_stat = JNI_CreateJavaVM(&jvm, (void **)&env, &jvm_args);

    //错误处理
    if (jvm_stat)
    {
        fprintf(stderr, "%s\n", "JVM Create Error!");
        exit(-1);
    }

    //找到类定义
    jclass my_jclass = env->FindClass("CXXTest");
    if (my_jclass)
    {
    	jobject obj = env->AllocObject(my_jclass);
    	if (!obj)
    	{
    		std::cerr << "obj error" << std::endl;
    		exit(-1);
    	}

    	jmethodID mid = env->GetMethodID(my_jclass, "say", "()V");
    	if (!mid)
    	{
    		std::cerr << "mid error" << std::endl;
    		exit(-1);
    	}
    	env->CallObjectMethod(obj, mid);
    }
    return 0;
}
class CXXTest
{
    public void say()
    {
        System.out.print("hello,world\n");
    }
};

Q:error while loading shared libraries: libjvm.so

先搜索对应的so文件,然后配置/etc/ld.so.conf里面的搜索路径

Q:centos 配置javac

直接安装openjdk-devel

Q:编译时函数未定义

编译时要连接libjvm.so不然无法通过编译,因为java没有将其安装到系统的lib中,因此需要添加搜索路径,使用-L

Q:获得参数签名

在调用下面这个函数时,最后一个参数要求传method的参数签名

jmethodID GetMethodID(jclass clazz, const char *name,const char *sig)

可以使用javap获得

javap -s -p XXX    #(XXX.class)

WARN : 初始化的env和线程绑定,如果在其他线程使用env会导致失败