c ++插件 – > JNI – > Java Classpath

我正在尝试为应用程序创建一个插件。 插件需要用c ++编写。 我想在Windows和Mac上使用插件,所以用Java编写插件会很棒。

我的问题是,还有一个使用Java的插件。 由于它们使用相同的主应用程序,因此已经有一个正在运行的JavaVM。

JavaVM *jvm = NULL; jsize jvm_count = 0; jint res=0; res = JNI_GetCreatedJavaVMs (&jvm, 1, &jvm_count); 

我的问题:如何更改/修改现有JavaVM的Classpath? 或者我如何创建新的/第二个JavaVM?

我试图通过JNI加载我的jar文件:

 /* URL CLASS */ jclass URLcls; URLcls = env->FindClass("java/net/URL"); /* URL CLASS CONSTRUCTOR*/ jmethodID URLclsMid; URLclsMid = env->GetMethodID(URLcls, "","(Ljava/lang/String;)V"); /* URL OBJECT */ jobject URLobj; jstr = env->NewStringUTF("file:/path/to/test/file/test.jar"); URLobj = env->NewObject(URLcls, URLclsMid, jstr); /* URL Array */ jobjectArray URLArray; URLArray = env->NewObjectArray(1, URLcls, URLobj); /*Thread Class*/ jclass ThreadCLS; ThreadCLS = env->FindClass("java/lang/Thread"); /*Static Method currentThread*/ jmethodID ThreadCLS_currentThread; ThreadCLS_currentThread = env->GetStaticMethodID(ThreadCLS, "currentThread","()Ljava/lang/Thread;"); /*get current Thread Object*/ jobject currentThread; currentThread = env->CallStaticObjectMethod(ThreadCLS, ThreadCLS_currentThread); /* getContextClassLoader method */ jmethodID currentThread_getContextClassLoader; currentThread_getContextClassLoader = env->GetMethodID(ThreadCLS, "getContextClassLoader","()Ljava/lang/ClassLoader;"); /* ClassLoader Class */ jclass ClassLoaderCLS; ClassLoaderCLS = env->FindClass("java/lang/ClassLoader"); /* get ClassLoader Object */ jobject classLoader = env->CallObjectMethod(currentThread, currentThread_getContextClassLoader); /* URLClassLoader Class */ jclass URLClassLoaderCLS; URLClassLoaderCLS = env->FindClass("java/net/URLClassLoader"); /* Static Method newInstance */ jmethodID URLClassLoaderCLS_newInstance; URLClassLoaderCLS_newInstance = env->GetStaticMethodID(URLClassLoaderCLS, "newInstance","([Ljava/net/URL;Ljava/lang/ClassLoader;)Ljava/net/URLClassLoader;"); /* get new URLClassLoader Instance */ jobject myURLClassLoaderInstance; myURLClassLoaderInstance = env->CallStaticObjectMethod(URLClassLoaderCLS, URLClassLoaderCLS_newInstance, URLArray, classLoader); /* get setContextClassLoader Method */ jmethodID currentThread_setContextClassLoader; currentThread_setContextClassLoader = env->GetMethodID(ThreadCLS, "setContextClassLoader","(Ljava/lang/ClassLoader;)V"); /* trying to set the ClassLoader from the current Thread */ env->CallVoidMethod(currentThread, currentThread_setContextClassLoader, myURLClassLoaderInstance); /* get loadClass Method */ jmethodID loadClass; loadClass = env->GetMethodID(URLClassLoaderCLS, "loadClass","(Ljava/lang/String;)Ljava/lang/Class;"); /* get a Class from my test.jar*/ jstring methodString = env->NewStringUTF("de.domain.sayHello"); jclass myClass = (jclass)env->CallObjectMethod(myURLClassLoaderInstance, loadClass, methodString); /*working till here*/ jmethodID myClassMethod; myClassMethod = env->GetMethodID(myClass, "doIt","()Ljava/lang/String;"); if (myClassMethod == NULL) { // Method of Class "de.domain.sayHello" not found } 

我该怎么做才能改变Classpath? 或加载我的jar文件?

谢谢丽莎

我已经解决了我的问题。 我没有设法以某种方式设置或影响Classpath,以便我可以使用:

 jmethodID myClassMethod; myClassMethod = env->GetMethodID(myClass, "doIt","()Ljava/lang/String;"); if (myClassMethod == NULL) { // Method of Class "de.domain.sayHello" not found } 

而不是我用Javareflection创建了我的类的对象。

找到我的Java类:(从我的问题的代码中“/ working to here /”之后)

 /* Class CLASS */ jclass Classcls = env->FindClass("java/lang/Class"); /* String CLASS */ jclass StringCls = env->FindClass("java/lang/String"); jstring methodString = env->NewStringUTF("de.domain.sayHello"); jclass myJavaClass = (jclass)env->CallObjectMethod(MyURLClassLoaderInstance, URLClassLoaderCLS_loadClass, methodString); 

从我的Java类中获取一个对象:

 /* CLASS newInstance Method*/ jmethodID ClassNewInstanceMid = env->GetMethodID(Classcls, "newInstance","()Ljava/lang/Object;"); jobject myObject = env->CallObjectMethod(myJavaClass, ClassNewInstanceMid); 

有了这个我从我的Java类得到了一个对象。 (默认构造函数被调用)

使用jobject我能够通过javareflection调用我的对象的方法。 我将带有Application路径的Sring传递给了我的Java方法。

在Java端我加载了应用程序:

 import java.io.File; public class sayHello { public static native void sayHi(String message, int times); public sayHello() { System.out.println("object created :) "); } public void doIt(String test) { File myfile = new File(test); if(myfile.exists()) System.load(myfile.getAbsolutePath()); else System.out.println("Something went wrong :( "); sayHi("C++ Funktion Call out of Java",5); } } 

在我的c ++插件中,我实现了这个function:

 JNIEXPORT void JNICALL Java_de_domain_sayHello_sayHi (JNIEnv *localEnv, jclass clazz, jstring message, jint times) { int myT = times; for(int i=0;iGetStringUTFChars(message, NULL)); } 

一个有趣的事情:在JNICALL方法(Java_de_domain_sayHello_sayHi)中,我能够通过JNI找到我的呼叫:

 jclass myCLS = env->FindClass("de/domain/sayHello"); if(myCLS != NULL){ //class found } 

在这个函数里面,我是否使用函数中的JNIEnv“localEnv”或“env”(全局变量)并不重要

谢谢丽莎