2015-04-24 3 views
0

Итак, я пытался найти способ запуска моего java-кода вместе с его зависимыми .jar-файлами в Visual C++-программе.Как добавить файлы зависимостей .jar в среду JNI C++

Я использовал следующий код для запуска Java-программы на C++ без каких-либо проблем.

Java Code

public class Sample2 
{ 
public static int intMethod(int n) 
{ 
    return n*n; 
} 
    public static boolean booleanMethod(boolean bool) 
    { 
    return !bool; 
    } 
} 

C++ код

// 1.cpp: главный файл проекта.

#include "stdafx.h" 
#include "jni.h" 
#include <windows.h> 
using namespace System; 


int CallJava() 
{ 
    JavaVM *jvm; /* denotes a Java VM */ 

    JNIEnv *env; /* pointer to native method interface */ 

    jint square; 

    jboolean not; 

    JavaVMInitArgs vm_args; /* JDK/JRE 6 VM initialization arguments */ 

    JavaVMOption *options = new JavaVMOption[1]; 

    options[0].optionString = "-Djava.class.path=C:\\JavaCode"; 

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

    HINSTANCE hinstLib; 

    hinstLib = LoadLibrary(TEXT("C:\\Program Files\\Java\\jdk1.6.0_45\\jre\\bin\\server\\jvm.dll")); 

if(hinstLib==0) 
{ 
    printf("Error"); 
    } 

    if(hinstLib!= NULL) 
{ 
    typedef jint (JNICALL *PtrCreateJavaVM)(JavaVM **, void **, void *); 

    PtrCreateJavaVM ptrCreateJavaVM =  (PtrCreateJavaVM)GetProcAddress(hinstLib,"JNI_CreateJavaVM"); 

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

    jclass cls = env->FindClass("Sample2"); 

    jmethodID mid; 

    if(cls !=0) 
    { 
    mid = env->GetStaticMethodID(cls,"intMethod","(I)I"); 
    if(mid !=0) 
    { 
    square = env->CallStaticIntMethod(cls, mid, 5);  
    printf("Result of intMethod: %d\n", square); 
    } 

    mid = env->GetStaticMethodID(cls, "booleanMethod", "(Z)Z"); 
    if(mid !=0) 
    { 
    not = env->CallStaticBooleanMethod(cls, mid, 1); 
    printf("Result of booleanMethod: %d\n", not); 
    } 
} 
    jvm->DestroyJavaVM(); 
} 
else 
{ 
    printf("Library is NULL"); 
} 
    Console::Read(); 
    return 0; 
} 

int main(array<System::String ^> ^args) 
{ 
CallJava(); 
Console::Read(); 
return 0; 
} 

Теперь, мой вопрос заключается в том, что, поскольку моя следующая java-программа использует несколько файлов jar из каталога.

Java Code

import javax.swing.*; 
import es.unex.sextante.core.Sextante; 
import es.unex.sextante.gui.core.SextanteGUI; 

public class Demo5 
{ 

public static class Starter implements Runnable 
{ 
    public void run() 
    { 
     Sextante.initialize(); 
     SextanteGUI.getGUIFactory().showModelerDialog(); 

    } 
    } 

    public static class GUI implements Runnable 
    { 
    public void run() 
    { 
     try 
     { 
      SwingUtilities.invokeAndWait(new Starter()); 
     } 
     catch (Exception exc) 
     { 
      throw new RuntimeException(exc); 
     } 
    } 
} 

    public static void run() 
    { 
    Thread gui = new Thread(new GUI()); 
    gui.start(); 
    } 

} 

Я могу скомпилировать и запустить код Java с помощью командной строки, используя следующий подход:

Compile: Javac -cp C: \ Lib \ sextante .jar; C: \ Lib \ sextante_gui.jar; Demo5.java

Запуск: java -cp c: \ Lib \ sextante.jar; c: \ Lib \ sextante_gui.jar; Demo5

Однако я не знаю, как добавить файлы jar в JNI-подход.

I tried the following ways: 

a. Метод 1: Следующий подход не работает:

JavaVMOption *options = new JavaVMOption[3]; 
    options[0].optionString = "-Djava.class.path=C:\\JavaCode"; 
    options[1].optionString = "-Djava.class.path=C:\\Lib\\sextante.jar"; 
    options[2].optionString = "-Djava.class.path=C:\\Lib\\sextante_gui.jar"; 

b. Метод 2: Я пытаюсь найти банки в вызове метода ...

Ничего не работает. Не могли бы вы помочь мне решить эту проблему?

Спасибо.

ответ

0

Код:

JavaVMOption *options = new JavaVMOption[3]; 
options[0].optionString = "-Djava.class.path=C:\\JavaCode"; 
options[1].optionString = "-Djava.class.path=C:\\Lib\\sextante.jar"; 
options[2].optionString = "-Djava.class.path=C:\\Lib\\sextante_gui.jar"; 

будет преобразована в команду

java.exe -Djava.class.path = C: \ JavaCode -Djava.class.path = C: \ Lib \ sextante.jar -Djava.class.path = C: \ Lib \ sextante_gui.jar

То, что вы, вероятно, хотите сделать это:

JavaVMOption *options = new JavaVMOption[1]; 
options[0].optionString = "-Djava.class.path=C:\\JavaCode;C:\\Lib\\sextante.jar;C:\\Lib\\sextante_gui.jar"; 

который получает преобразуется в

java.exe -Djava.class.path = C: \ JavaCode; C: \ Lib \ sextante.jar; C: \ Lib \ sextante_gui.jar

+0

Спасибо Mike за ответ. К сожалению, после того, как я изменил его так, как вы упомянули, я все равно получаю ту же ошибку, что класс не нашел ошибку. Я пробовал так, как вы упомянули, и я тоже пробовал это следующим образом. JavaVMOption * options = new JavaVMOption [1]; options [0] .optionString = "-Djava.class.path = C: \\ APP3; C: \\ APP3 \\ *. jar"; Мне интересно, есть ли какие-либо аргументы jar-файлов, которые мне нужно передать в CallStaticVoidMethod() –

+0

Вы не можете подстановочные параметры JVM, подобные этому. Обычно использование «*» (также называемое «globbing») - это то, что обрабатывается средой оболочки, а не JVM. – technomage

+1

Вам нужно перечислить каждый файл jar, который вы используете индивидуально. Обращение к каталогу работает только для ссылок на разделенные файлы классов. – technomage

Смежные вопросы