Как получить доступ к методу Java в приложении на C ++
Просто вопрос: можно ли вызвать java-функцию из c / c ++?
- «Некомпилируемый исходный код» RuntimeException в netbeans
- Правильное использование флеша () в JPA / Hibernate
- В JPA 2, используя CriteriaQuery, как подсчитать результаты
- Автоматическое изменение размера javafx и добавление кнопок
- Каков пример утиной печати на Java?
- Как автоматически генерировать N "разных" цветов?
- Java: Является ли assertEquals (String, String) надежным?
- PDF-переупорядочение страницы с помощью itext
Да, вы можете, но это немного запутанно и работает безопасным способом с reflectionм / не-типом (пример использует C ++ api, который немного чище, чем версия C). В этом случае он создает экземпляр Java VM из кода C. Если ваш родной вызов сначала вызывается из Java, тогда нет необходимости создавать экземпляр виртуальной машины
#include #include int main(int argc, char** argv) { JavaVM *vm; JNIEnv *env; JavaVMInitArgs vm_args; vm_args.version = JNI_VERSION_1_2; vm_args.nOptions = 0; vm_args.ignoreUnrecognized = 1; // Construct a VM jint res = JNI_CreateJavaVM(&vm, (void **)&env, &vm_args); // Construct a String jstring jstr = env->NewStringUTF("Hello World"); // First get the class that contains the method you need to call jclass clazz = env->FindClass("java/lang/String"); // Get the method that you want to call jmethodID to_lower = env->GetMethodID(clazz, "toLowerCase", "()Ljava/lang/String;"); // Call the method on the object jobject result = env->CallObjectMethod(jstr, to_lower); // Get a C-style string const char* str = env->GetStringUTFChars((jstring) result, NULL); printf("%s\n", str); // Clean up env->ReleaseStringUTFChars(jstr, str); // Shutdown the VM. vm->DestroyJavaVM(); }
Чтобы скомпилировать (на Ubuntu):
g++ -I/usr/lib/jvm/java-6-sun/include \ -I/usr/lib/jvm/java-6-sun/include/linux \ -L/usr/lib/jvm/java-6-sun/jre/lib/i386/server/ -ljvm jnitest.cc
Обратите внимание: что код возврата из каждого из этих методов должен быть проверен для правильной обработки ошибок (я проигнорировал это для удобства). Например
str = env->GetStringUTFChars(jstr, NULL); if (str == NULL) { return; /* out of memory */ }
Да, но вам нужно сделать это через JNI: http://java.sun.com/javase/6/docs/technotes/guides/jni/index.html
Есть много способов. Вот некоторые идеи. Кроме того, коммерческие мосты Java-COM позволяют COM-коммуникацию от c ++ до java (если вы используете Windows). Вы также должны посмотреть на CNI .
Взгляните на API-интерфейс вызова . Это позволяет загружать и запускать JVM из собственного приложения, а затем вызывать методы из него из приложения.
Вкратце (из связанного документа)
/* load and initialize a Java VM, return a JNI interface * pointer in env */ JNI_CreateJavaVM(&jvm, &env, &vm_args); /* invoke the Main.test method using the JNI */ jclass cls = env->FindClass("Main"); jmethodID mid = env->GetStaticMethodID(cls, "test", "(I)V"); env->CallStaticVoidMethod(cls, mid, 100);
Да, вы можете вызвать функцию Java из C ++ или C, но если вы не используете что-то вроде COM или CORBA (или другого стороннего инструмента, о котором я, вероятно, не знаю), вам придется сделать это в контексте JNI.
Вся процедура вызова Java-метода из собственного кода описана в главе 4 раздела 4.2 «Методы вызова» в руководстве Sun JNI pdf, которое вы можете найти здесь .
Следующая функция позволяет создать виртуальную машину.
JNIEnv* create_vm(JavaVM ** jvm) { JNIEnv *env; JavaVMInitArgs vm_args; JavaVMOption options[2]; options[0].optionString = "-Djava.class.path=."; options[1].optionString = "-DXcheck:jni:pedantic"; vm_args.version = JNI_VERSION_1_6; vm_args.nOptions = 2; vm_args.options = options; vm_args.ignoreUnrecognized = JNI_TRUE; // remove unrecognized options int ret = JNI_CreateJavaVM(jvm, (void**) &env, &vm_args); if (ret < 0) printf("\n<<<<< Unable to Launch JVM >>>>>\n"); return env; }
Скомпилируйте знаменитую программу Hello World . Следующая функция пытается вызвать основной метод программы HelloWorld.
int main(int argc, char* argv[]) { JNIEnv* env; JavaVM* jvm; env = create_vm(&jvm); if (env == NULL) return 1; jclass myClass = NULL; jmethodID main = NULL; myClass = env->FindClass("HelloWorld"); if (myClass != NULL) main = env->GetStaticMethodID(myClass, "main", "([Ljava/lang/String;)V"); else printf("Unable to find the requested class\n"); if (main != NULL) { env->CallStaticVoidMethod( myClass, main, " "); }else printf("main method not found") ; jvm->DestroyJavaVM(); return 0; }
Теперь добавьте функцию create_vm и главную функцию в один файл cpp, включите jni.h и скомпилируйте его. Я использовал MinGW на windowsх.
g++ -D_JNI_IMPLEMENTATION_ -I"C:\Program Files\Java\jdk1.6.0_32\include" -I"C:\Program Files\Java\jdk1.6.0_32\include\win32" hello.cpp -L"C:\Program Files\Java\jre6\bin\client" -ljvm -o hello.exe
Exection Теперь, если вы запустите созданный exe, вы получите сообщение об ошибке. jvm.dll не найден . Поместите C:\Program Files\Java\jre6\bin\client
в переменную среды PATH. Теперь вы можете запустить exe-файл.
Примечание. Не перемещайте файл jvm.dll.
После кодирования вышеприведенных примеров вам нужно выполнить некоторую настройку в своем проекте.
Шаги по связыванию jvm.lib с вашим проектом в Visual Studio:
- Щелкните правой кнопкой мыши по проекту -> свойства.
- В диалоговом окне «Свойства» добавьте jvm.lib в области Linker-> Input-> AdditionalDependencies.
- Наконец, напишите путь jvm.lib (например, «C: \ Program Files \ Java \ jdk1.7.0_60 \ lib») в Linker-> General-> AdditionalLibraryDirectories
После этих шагов ваш проект может ссылаться на jvm и работать хорошо.