Указание пути в программе на C ++ - PullRequest
0 голосов
/ 01 декабря 2018

Я пишу средство запуска Java на C для Windows, которое запускается в среде выполнения Java, которая находится в каталоге моей программы (то есть распространяется с моей программой).У меня есть код, который работает (указан ниже), но для выполнения ему нужно jvm.dll в его% PATH%.

Я хотел бы добавить строку в мой код, которая сообщает программе, чтобы она зарегистрировала <executable's directory>/jre/bin/server для jvm.dll, чтобы исполняемый файл можно было запустить, просто дважды щелкнув мышью.

Прямо сейчаскогда я запускаю его, он говорит: «Программа не может запуститься, потому что на вашем компьютере отсутствует jvm.dll. Попробуйте переустановить программу, чтобы решить эту проблему».

Если я переместу свой простой исполняемый файл в jre\bin\serverгде jvm.dll находится и попробуйте запустить его, это работает. Так что мне просто нужно сказать моей программе искать dll в определенном другом месте, и я буду в порядке.

Основываясь на том, что я нашел путем поиска, я попыталсяHINSTANCE hVM = LoadLibrary("jre\\bin\\server\\jvm.dll");.К сожалению, это не работает.

Как мне достичь этой цели?Я не программист на C или Windows, поэтому прошу прощения, если вопрос является основным.

#include <jni.h> 
#include <windows.h>

int main() {
   HINSTANCE hVM = LoadLibrary("jre\\bin\\server\\jvm.dll"); //Does not work

   JavaVM *jvm; 
   JNIEnv *env;
   JavaVMInitArgs vm_args; 
   JavaVMOption* options = new JavaVMOption[1];

   int index = 0;
   options[index].optionString = (char *)"-Djava.class.path=./main.jar";

   vm_args.version = JNI_VERSION_10;
   vm_args.nOptions = 1;
   vm_args.options = options;
   vm_args.ignoreUnrecognized = false;
   JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
   delete options;

   jmethodID main = NULL;
   jclass cls = NULL;

   cls = env->FindClass("net/joshuad/test/Main");
   if(env->ExceptionCheck()) {  
      env->ExceptionDescribe();
      env->ExceptionClear();
   }

   if (cls != NULL) {
      main = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V");
   } else {
      printf("Unable to find the requested class\n");
   }

   if (main != NULL) {
      env->CallStaticVoidMethod( cls, main, " ");
   } else {
      printf("main method not found") ;
   }

   jvm->DestroyJavaVM();
   return 0;
}

Ответы [ 2 ]

0 голосов
/ 01 декабря 2018

Я понял это.Чтобы ссылаться на встроенную JRE таким способом, нам нужно ссылаться явно , а не неявно, чтобы наша программа не пыталась соединиться перед запуском, а затем вызывать JNI_CreateJavaVM с указателем на функциючем при непосредственном вызове функции.

Отказ от ответственности - я ужасный программист на C ++, и хотя это работает, я понятия не имею, использует ли он передовой опыт.Используйте на свой страх и риск.

Вот рабочий пример для тех, кто пытается это сделать:

#include <jni.h> 
#include <windows.h>

typedef UINT (CALLBACK* JVMDLLFunction)( JavaVM**, void**, JavaVMInitArgs * );

    int main() {        
        HINSTANCE jvmDLL = LoadLibrary(".\\jre\\bin\\server\\jvm.dll");

        if ( !jvmDLL ) {
             printf("failed to find jvm.dll at specified location, exiting.\n");
             return 1;
        }

        JVMDLLFunction createJavaVMFunction = (JVMDLLFunction)GetProcAddress(jvmDLL, "JNI_CreateJavaVM");

        if ( ! createJavaVMFunction ) {
             printf("Failed to get pointer to JNI_CreateJavaVM function from jvm.dll, exiting\n");
             return 1;
        } 

        JavaVM *jvm; 
        JNIEnv *env;
        JavaVMInitArgs vm_args; 
        JavaVMOption* options = new JavaVMOption[1];

        int index = 0;
        options[index].optionString = (char *)"-Djava.class.path=./main.jar";

        vm_args.version = JNI_VERSION_10;
        vm_args.nOptions = 1;
        vm_args.options = options;
        vm_args.ignoreUnrecognized = false;

        createJavaVMFunction( &jvm, (void**)&env, &vm_args );

        //JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
        delete options;

        jmethodID main = NULL;
        jclass cls = NULL;

        cls = env->FindClass("net/joshuad/test/Main");
        if(env->ExceptionCheck()) {  
          env->ExceptionDescribe();
          env->ExceptionClear();
        }

        if (cls != NULL) {
          main = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V");
        } else {
          printf("Unable to find the requested class\n");
        }

        if (main != NULL) {
          env->CallStaticVoidMethod( cls, main, " ");
        } else {
          printf("main method not found") ;
        }

        jvm->DestroyJavaVM();
        return 0;
    }
0 голосов
/ 01 декабря 2018

Указанный путь будет работать только в том случае, если ваша программа написана в том же каталоге, где находится папка jre.В противном случае вам нужно будет указать полное местоположение, например "C: \\ jdk \\ jrebin \ server \\ jvm.dll"

...