C++ 调用 Java篇
1. http://public0821.javaeye.com/blog/423941 这一篇是用C++6.0测试的,按照这个来,基本上可以成功,不过先把JAVA的环境变量设置好,表现为输入javac会出来一堆信息。
2. VS2005 开发
(1).【文件】->【项目】->选中visual C++下面的 win32项->【win32控制台程序】(这个根据你的需要选择),输入项目名,存放路径。工程新建成功。
(2 ).设置工程
选中工程,右键【属性】,【配置属性】【C/C++】【常规】【附加包含目录】输入"C:/Program Files/Java/jdk1.6.0_10/lib";"C:/ProgramFiles/Java/jdk1.6.0_10/include/win32";"C:/Program Files/Java/jdk1.6.0_10/include"
(3)工程代码
在CPP文件中加入代码,见附录A
(4)Java代码,见附录B
(5).编译完 java文件,将.java和.class文件放置于同一文件夹下,名为test(名字随便改), 将test文件夹放置于CPP文件的同一层目录下。
(6). 运行程序,出现结果
(7) 注意:
1. 如果你完全复制下面的这些代码,请注意对java文件做适当修改
package test;这一句表明java文件必须在test文件夹下面,
在代码中会有下面这两句代码,它是设置读取java的class文件的关键
options[1].optionString = "-Djava.class.path=.;";
jclass cls = env->FindClass("test/Demo");
如果你将test文件夹取其他的名字,请注意处理package test;否则cls的获取将会失败。
2. //获取类中的方法,最后一个参数是方法的签名,通过javap -s -p 文件名可以获得
// jmethodID mid = env->GetMethodID(cls, "append","(Ljava/lang/String;I)Ljava/lang/String;");
jmethodID mid = env->GetMethodID(cls, "myTest","()Ljava/lang/String;");
附录A
// ctoj.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "windows.h"
#include "jni.h"
#include <string>
#include <iostream>
using namespace std;
jstring CStringToJString(JNIEnv *env, const char * str);
int JStringToCString (JNIEnv *env, jstring str,char *c_buffer);
#define TEST
int _tmain(int argc, _TCHAR* argv[])
{
//定义一个函数指针,下面用来指向JVM中的JNI_CreateJavaVM函数
typedef jint (WINAPI *PFunCreateJavaVM)(JavaVM **, void **, void *);
int res;
JavaVMInitArgs vm_args;
JavaVMOption options[3];
JavaVM *jvm;
JNIEnv *env;
/*设置初始化参数*/
//disable JIT,这是JNI文档中的解释,具体意义不是很清楚,能取哪些值也不清楚。
//从JNI文档里给的示例代码中搬过来的
options[0].optionString = "-Djava.compiler=NONE";
//设置classpath,如果程序用到了第三方的JAR包,也可以在这里面包含进来
//options[1].optionString = "-Djava.class.path=.;c://";
//options[1].optionString = "-Djava.class.path=.;f://BMP//ctoj//ctoj//;c://";
#ifndef TEST
options[1].optionString = "-Djava.class.path=.;c://";
#else
options[1].optionString = "-Djava.class.path=.;";
#endif
//设置显示消息的类型,取值有gc、class和jni,如果一次取多个的话值之间用逗号格开,如-verbose:gc,class
//该参数可以用来观察C++调用JAVA的过程,设置该参数后,程序会在标准输出设备上打印调用的相关信息
options[2].optionString = "-verbose:NONE";
//设置版本号,版本号有JNI_VERSION_1_1,JNI_VERSION_1_2和JNI_VERSION_1_4
//选择一个根你安装的JRE版本最近的版本号即可,不过你的JRE版本一定要等于或者高于指定的版本号
vm_args.version = JNI_VERSION_1_4;
vm_args.nOptions = 3;
vm_args.options = options;
//该参数指定是否忽略非标准的参数,如果填JNI_FLASE,当遇到非标准参数时,JNI_CreateJavaVM会返回JNI_ERR
vm_args.ignoreUnrecognized = JNI_TRUE;
//加载JVM.DLL动态库
HINSTANCE hInstance = ::LoadLibrary(L"C://Program Files//Java//jdk1.6.0_10//jre//bin//client//jvm.dll");
if (hInstance == NULL)
{
return false;
}
//取得里面的JNI_CreateJavaVM函数指针
PFunCreateJavaVM funCreateJavaVM = (PFunCreateJavaVM)::GetProcAddress(hInstance, "JNI_CreateJavaVM");
//调用JNI_CreateJavaVM创建虚拟机
res = (*funCreateJavaVM)(&jvm, (void**)&env, &vm_args);
if (res < 0)
{
return -1;
}
//查找test.Demo类,返回JAVA类的CLASS对象
jclass cls = env->FindClass("jni/Demo");