• JNI编程:c++ 调用java 对象


    用C++调用Java的java.lang.String类为例:

    1.      Object类出创建JVM。

    使用Java类之前必须要创建JVM环境。JDK由java.exe来完成。本文有Object类的静态方法BeginJVM来创建,用EndJVM来关闭。

    创建JVM之后会在创建2个变量,分别是JNIEnv* env和JavaVM* jvm,JNIEnv上文已经说明,JavaVM,顾名思义,代表Java虚拟机,用它来关闭JVM。

    Object类的头文件

    #include "jni.h"

    class Object

    {

    public:

                  static bool BeginJVM();

                  static bool EndJVM();

                  Object();

                  virtual ~Object();

    protected:

                   static JNIEnv* env;

                   static JavaVM* jvm;

    };

    object.cpp代码

    #include "stdafx.h"

    #include "JavaClasses.h"

    #include "Object.h"

    Object::Object()

    {}

    Object::~Object()

    {}

    JNIEnv* Object::env=NULL;

    JavaVM* Object::jvm=NULL;

    //创建JVM

    bool Object::BeginJVM()

    {

                  JavaVMOption options[3];

                  JavaVMInitArgs vm_args;

    //各种参数

                  options[0].optionString="-Xmx128m";

                  options[1].optionString="-Verbose:gc";

                  options[2].optionString="-Djava.class.path=.";

                  vm_args.version=JNI_VERSION_1_2;

                  vm_args.options=options;

                  vm_args.nOptions=3;

    //创建JVM,获得jvm和env

                  int res = JNI_CreateJavaVM(&jvm,(void **)&env, &vm_args);

                  return true;

    }

    bool Object::EndJVM()

    {

    //关闭JVM

                  jvm->DestroyJavaVM();

                  return true;

    }

    2.      C++的String类调用java.lang.String类方法

    编写C++版的String类,调用java String类方法。调用的方法如下:

                  String replaceAll(String regex, String replacement);

                  boolean endsWith(String str);

                  int indexOf(String str);

                  int compareTo(String anotherString);

                  char charAt(int i);

    String的头文件:

    class String :public Object

    {

    public:

    //与要调用的Java方法名一致。

                  const char * replaceAll(char *regex,char *replacement);

                  bool endsWith(char * str);

                  int indexOf(char * str);

                  int compareTo(char *anotherString);

                  char charAt(int i);

                  String(char *str);

                  virtual ~String();

    };

    实现:

    #include "stdafx.h"

    #include "String.h"

    #include "jni.h"

    using namespace std;

    jclass clazz;    //全局变量,用来传递class

    jobject object; //全局变量,用来传递object

    String::String(char *str)

    {

        jstring jstr;

                  if (Object::env ==NULL)

                  {

                                cout << "JVM is not created" << endl;

                                exit(-1);

                  }

                  //获得java.lang.String类

                  clazz=Object::env->FindClass("java/lang/String");

                  if (clazz ==0 ){

                                cout << "Class is not found" << endl;

                                exit(-1);

                  }

                  //获得String(String str)构造体

                  jmethodID mid= Object::env->GetMethodID(clazz,"<init>", "(Ljava/lang/String;)V");

                  if (mid==0){

                                cerr<< "GetMethodID Error for class" << endl;

                                exit(-1);

                  }

    //将字符串封装为jstring。

        jstr = Object::env->NewStringUTF(str);

        if (jstr == 0) {

                                cerr << "Out of memory" <<endl;

            exit(-1);

        }

                  cout << "invoking method" << endl;

    //创建一个java.lang.String对象。

                  object=Object::env->NewObject(clazz,mid,jstr);

    }

    String::~String()

    {}

    char String::charAt(int i)

    {

                  if (Object::env ==NULL)

                  {

                                cout << "JVM is not created" << endl;

                                exit(-1);

                  }

                  if (clazz ==0 ){

                                cout << "Class is not found" << endl;

                                exit(-1);

                  }

                  if (object ==0 ){

                                cout << "String object is not created" << endl;

                                exit(-1);

                  }

                  jmethodID mid;

                  //获得charAt方法,(I)C表示 参数为int型,返回char型。详细参见JNI规范

                  mid= Object::env->GetMethodID(clazz,"charAt", "(I)C");

                  if (mid==0){

                                cerr<< "GetMethodID Error for class" << endl;

                                exit(-1);

                  }

                  jint ji=i;

                  cout << "invoking method" << endl;

    //调用charAt

                  jchar z=Object::env->CallCharMethod(object,mid,i);

    //返回结果。

                  return z;

    }

    int String::compareTo(char *anotherString)

    {

                  if (Object::env ==NULL)

                  {

                                cout << "JVM is not created" << endl;

                                exit(-1);

                  }

                  if (clazz ==0 ){

                                cout << "Class is not found" << endl;

                                exit(-1);

                  }

                  if (object ==0 ){

                                cout << "String object is not created" << endl;

                                exit(-1);

                  }

                  jmethodID mid;

    //(Ljava/lang/String;)I表示参数为java.lang.String,返回int

                  mid= Object::env->GetMethodID(clazz,"compareTo", "(Ljava/lang/String;)I");

                  if (mid==0){

                                cerr<< "GetMethodID Error for class" << endl;

                                exit(-1);

                  }

                  jstring jstr = Object::env->NewStringUTF(anotherString);

                  cout << "invoking method" << endl;

    //调用方法

    jint z=Object::env->CallIntMethod(object,mid,jstr);

    //返回结果

                  return z;

    }

    int String::indexOf(char *str)

    {

                  if (Object::env ==NULL)

                  {

                                cout << "JVM is not created" << endl;

                                exit(-1);

                  }

                  if (clazz ==0 ){

                                cout << "Class is not found" << endl;

                                exit(-1);

                  }

                  if (object ==0 ){

                                cout << "String object is not created" << endl;

                                exit(-1);

                  }

                  jmethodID mid;

                  mid= Object::env->GetMethodID(clazz,"indexOf", "(Ljava/lang/String;)I");

                  if (mid==0){

                                cerr<< "GetMethodID Error for class" << endl;

                                exit(-1);

                  }

                  jstring jstr = Object::env->NewStringUTF(str);

                  cout << "invoking method" << endl;

                  jint z=Object::env->CallIntMethod(object,mid,jstr);

                  return z;

    }

    bool String::endsWith(char *str)

    {

                  if (Object::env ==NULL)

                  {

                                cout << "JVM is not created" << endl;

                                exit(-1);

                  }

                  if (clazz ==0 ){

                                cout << "Class is not found" << endl;

                                exit(-1);

                  }

                  if (object ==0 ){

                                cout << "String object is not created" << endl;

                                exit(-1);

                  }

                  jmethodID mid;

                  mid= Object::env->GetMethodID(clazz,"endsWith", "(Ljava/lang/String;)Z");

                  if (mid==0){

                                cerr<< "GetMethodID Error for class" << endl;

                                exit(-1);

                  }

                  jstring jstr = Object::env->NewStringUTF(str);

                  cout << "invoking method" << endl;

                  bool z=Object::env->CallBooleanMethod(object,mid,jstr);

                 

                  return z;

    }

    const char * String::replaceAll(char *regex, char *replacement)

    {

                  if (Object::env ==NULL)

                  {

                                cout << "JVM is not created" << endl;

                                exit(-1);

                  }

                  if (clazz ==0 ){

                                cout << "Class is not found" << endl;

                                exit(-1);

                  }

                  if (object ==0 ){

                                cout << "String object is not created" << endl;

                                exit(-1);

                  }

                  jmethodID mid;

                  mid= Object::env->GetMethodID(clazz,"replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");

                  if (mid==0){

                                cerr<< "GetMethodID Error for class" << endl;

                                exit(-1);

                  }

                  jvalue array[2];

                  jstring jreg = Object::env->NewStringUTF(regex);

                  jstring jstr = Object::env->NewStringUTF(replacement);

                  array[0].l=jreg;

                  array[1].l=jstr;

                  cout << "invoking method" << endl;

    //传入参数,调用replaceAll方法

                  jobject z=Object::env->CallObjectMethodA(object,mid,array);

                  const char *result=Object::env->GetStringUTFChars((jstring)z, 0);

                  return (const char *)result;

    }

    3.测试

    编写测试代码

    using namespace std;

    int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])

    {

                  int nRetCode = 0;

                  if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))

                  {

                                cerr << _T("Fatal Error: MFC initialization failed") << endl;

                                nRetCode = 1;

                  }

                  else

                  {

    //创建JVM

                                Object::BeginJVM();

                               

                                String test("hello");

                                //调用replaceAll

                                const char *result=test.replaceAll("l","z");

                                //返回结果

                                cout<< result <<endl;

                                //关闭JVM

                                Object::EndJVM();

                  }

                  return nRetCode;

    }

    4.运行

    编译需要 jni.h和jvm.lib文件。

    jni.h在[JAVA_HOME]include

    jvm.lib在[JAVA_HOME]lib

    运行需要jvm.dll

    jvm.dll在[JAVA_HOME] jreinclient

    运行结果如下:

    invoking method

    invoking method

    hezzo

    Press any key to continue

  • 相关阅读:
    DOM(文档对象模型)
    客户端检测
    mysql之触发器
    mysql之select(二)
    浅谈mysql中varchar(m)与char(n)的区别与联系
    mysql之select(一)
    mysql(一)
    mysql5.7.11安装遇到的问题
    Java 网络编程(二)
    Java 网络编程(一)
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318653.html
Copyright © 2020-2023  润新知