Java 如何在C++;应用
只是一个简单的问题:Java 如何在C++;应用,java,c++,c,Java,C++,C,只是一个简单的问题: 可以从c/c++调用java函数吗?是的,但是必须通过JNI来实现:有很多方法。有一些想法。此外,商用java com桥允许COM通信从C++到java(如果您使用Windows)。你也应该看看.是的,你可以,但是它有点复杂,并且工作在反射/非类型安全的方式中(例子使用比C版本更干净的C++ API)。在本例中,它从C代码中创建一个JavaVM实例。如果您的本机调用是首先从Java调用的,那么就不需要构造VM实例 #include<jni.h> #include
可以从c/c++调用java函数吗?是的,但是必须通过JNI来实现:有很多方法。有一些想法。此外,商用java com桥允许COM通信从C++到java(如果您使用Windows)。你也应该看看.
是的,你可以,但是它有点复杂,并且工作在反射/非类型安全的方式中(例子使用比C版本更干净的C++ API)。在本例中,它从C代码中创建一个JavaVM实例。如果您的本机调用是首先从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();
}
注意:为了实现正确的错误处理,应该检查每个方法的返回代码(为了方便起见,我忽略了这一点)。例如
是的,你可以从C++或C调用java函数,但是除非你使用的是COM或CORBA(或者另一个第三方工具,我可能不知道),否则你必须在JNI的上下文中这样做。 从本机代码调用Java方法的整个过程在Sun的JNI指南pdf中的第4.2节“调用方法”中的第4章中进行了描述,您可以找到。
请查看。这使您能够从本机应用程序中加载和启动JVM,然后从应用程序中对其调用方法 简要说明(来自链接文档)下面的函数允许您创建VM
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;
}
现在将create_vm函数和main函数放在一个cpp文件中,包括jni.h并编译它。我在窗户上用明格
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
执行
现在,如果运行创建的exe,将出现错误。
将C:\Program Files\Java\jre6\bin\client
放入PATH环境变量中。现在你可以
运行exe文件
注意:不要替换jvm.dll文件。在编写上述示例后,您需要对项目进行一些配置 在Visual Studio中将jvm.lib链接到项目的步骤:
- 右键单击项目->属性
- 在属性对话框中,在链接器->输入->附加依赖项区域下添加jvm.lib
- 最后在下面编写jvm.lib路径(如“C:\Program Files\Java\jdk1.7.0\U 60\lib”) 链接器->常规->附加库目录
在这些步骤之后,您的项目可以链接到JVM并工作得很好。
我已经看到JNI用于从java调用C++。不知道java java C++的用法也很奇怪。我一直都看到它更常用于从Java提供对C++库的访问,但是它是双向的。@ CBBailey“提供从Java访问C++库”的意思是“从Java调用C++”。不我觉得你们说的是同一句话:“常用于从Java调用[C++代码”。+1就是一个例子。可能还想包括设置头、函数签名等的链接/示例?您的解决方案很棒,但如何加载或设置我们创建的类路径,例如HelloWorld.java,即env->FindClass(“HelloWorld”)谢天谢地,这对我有用。我向上投票,让我只提到我使用了“-Wl,-rpath,${lib_dir}”,当然没有引号,其中lib_dir是libjvm.so所在的目录(我使用了'find/usr/lib/jvm/-name“libjvm.so',并将dirname作为我环境中实际的jvm lib目录)。链接(或编译/链接)步骤(例如g++)中的-Wl,-rpath,${lib_dir}使您不必在运行时在LD_LIBRARY_路径中指定lib_dir。
/* 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);
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;
}
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;
}
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