Просто вопрос: Можно ли вызвать java-функцию из c/С++?
Как получить доступ к методу Java в приложении на С++
Ответ 1
Да, вы можете, но он немного запутан, и работает безопасным способом с отражающим/не-типом (пример использует С++ api, который немного чище, чем версия C). В этом случае он создает экземпляр Java VM из кода C. Если ваш родной вызов сначала вызывается из Java, тогда нет необходимости создавать экземпляр VM
#include<jni.h>
#include<stdio.h>
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 */
}
Ответ 2
Да, но вам нужно сделать это через JNI: http://java.sun.com/javase/6/docs/technotes/guides/jni/index.html
Ответ 3
Есть много способов. Вот несколько идей. Кроме того, коммерческие мосты Java-COM позволяют COM-коммуникацию от С++ до java (если вы используете Windows). Вы также должны посмотреть CNI.
Ответ 4
Да, вы можете вызывать функцию Java из С++ или C, но если вы не используете что-то вроде COM или CORBA (или другого стороннего инструмента, о котором я, вероятно, не знаю), вам придется это сделать в контексте JNI.
Вся процедура вызова метода Java из собственного кода описана в главе 4 раздела 4.2, называемой "Методы вызова" в руководстве Sun JNI pdf, в котором вы можете найти .
Ответ 5
Взгляните на 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);
Ответ 6
Следующая функция позволяет создать виртуальную машину.
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 на окнах.
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.
Ответ 7
После кодирования вышеприведенных примеров вам нужно сделать некоторую конфигурацию в своем проекте.
Шаги по связыванию jvm.lib с вашим проектом в Visual Studio:
- Щелкните правой кнопкой мыши проект → свойства.
- В диалоговом окне "Свойства" добавьте jvm.lib в области "Linker- > Input- > AdditionalDependencies".
- Наконец, напишите путь jvm.lib(например, "C:\Program Files\Java\jdk1.7.0_60\lib" ) в Linker- > Общие- > AdditionalLibraryDirectories
После этих шагов ваш проект может ссылаться на jvm и работать хорошо.