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

原文地址:https://www.cnblogs.com/hzcya1995/p/13318653.html