#include <windows.h>
#include <jni.h>
#include <string>
using namespace std;void vShowError(string sErrorMessage);
void vShowLastError(string sErrorMessage);
void vDestroyVM(JNIEnv *env, JavaVM *jvm);
void vAddOption(string& sName);JavaVMOption* vm_options;
int mctOptions = 0;
int mctOptionCapacity = 0;
boolean GetApplicationHome(char *buf, jint sz);
typedef jint (CALLBACK *CreateJavaVM)(JavaVM **pvm, JNIEnv **penv, void *args);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){
JNIEnv *env;
JavaVM *jvm;
jint jintVMStartupReturnValue;
jclass jclassStartup;
jmethodID midStartup; // 确定各种文件所在的路径
// -应用的主目录
char home[2000];
if (!GetApplicationHome(home, sizeof(home))) {
vShowError("不能确定应用的主目录。");
return 0;
}
string sAppHome(home);
sAppHome="C:\\j2sdk1.4.2_03";
string sOption_AppHome = "-Dapplication.home=" + sAppHome;
string sJREPath = sAppHome + "\\jre";
// -VM路径
string sRuntimePath = sJREPath + "\\bin\\server\\";
string sJVMpath = sRuntimePath + "jvm.dll";
// -启动路径
string sBootPath = sJREPath + "\\lib";
string sOption_BootPath = "-Dsun.boot.class.path=" + sBootPath;
// -CLASSPATH
// string sClassPath = sAppHome + "\\classes";
string sClassPath = "C:\\CuCommonNote";
string sOption_ClassPath = "-Djava.class.path=" + sClassPath;
// 设置VM参数
// vAddOption(string("-cp ./;./lib/log4j-1.2.8.jar"));
vAddOption(sOption_ClassPath);
vAddOption(sOption_AppHome);
// VM初始化参数
JavaVMInitArgs vm_args;
vm_args.version = 0x00010002;
vm_args.options = vm_options;
vm_args.nOptions = mctOptions;
vm_args.ignoreUnrecognized = JNI_TRUE;
// 装入JVM库
HINSTANCE hJVM = LoadLibrary(sJVMpath.c_str());
if( hJVM == NULL ){
vShowLastError("不能从下面的路径装入JVM:" + sJVMpath);
return 0;
}
// 启动1.2/3/4 VM
CreateJavaVM lpfnCreateJavaVM = (CreateJavaVM) GetProcAddress(hJVM, "JNI_CreateJavaVM");
jintVMStartupReturnValue = (*lpfnCreateJavaVM) (&jvm, &env, &vm_args);
// 是否成功?
if (jintVMStartupReturnValue < 0) {
string sErrorMessage = "创建VM失败。";
vShowError(sErrorMessage);
vDestroyVM(env, jvm);
return 0;
}
// 要启动的类
string sStartupClass = "CuCommonNote/CuCommonNote";
// 注意句点符号已经被转换成斜杠
jclassStartup = env->FindClass(sStartupClass.c_str());
if (jclassStartup == NULL) {
string sErrorMessage ="找不到启动类[" +sStartupClass + "]";
vShowError(sErrorMessage);
vDestroyVM(env, jvm);
return 0;
}
// 要启动的方法
string sStartupMethod_Identifier = "main";
string sStartupMethod_TypeDescriptor ="([Ljava/lang/String;)V";
midStartup = env->GetStaticMethodID(jclassStartup,
sStartupMethod_Identifier.c_str(),
sStartupMethod_TypeDescriptor.c_str());
if (midStartup == NULL) {
string sErrorMessage = "找不到启动方法["+ sStartupClass + "."+ sStartupMethod_Identifier
+ "],类型描述符是[" + sStartupMethod_TypeDescriptor + "]";
vShowError(sErrorMessage);
vDestroyVM(env, jvm);
return 0;
}
// 构造启动方法的参数
jstring jstringExampleArg;
jclass jclassString;
jobjectArray jobjectArray_args;
jstringExampleArg = env->NewStringUTF("string1");
if (jstringExampleArg == NULL){
vDestroyVM(env, jvm);
return 0;
}
jclassString = env->FindClass("java/lang/String");
jobjectArray_args = env->NewObjectArray(1, jclassString, jstringExampleArg);
if (jobjectArray_args == NULL){
vDestroyVM(env, jvm);
return 0;
}
// 调用启动方法启动Java程序
env->CallStaticVoidMethod(jclassStartup, midStartup, jobjectArray_args);
// 在退出之前尝试分离主线程
if (jvm->DetachCurrentThread() != 0) {
vShowError("分离主线程失败。\n");
}
// 只要还有非守护线程,下面的调用将一直被挂起
jvm->DestroyJavaVM();
return 0;
}
void vDestroyVM(JNIEnv *env, JavaVM *jvm){
if (env->ExceptionOccurred()) {
env->ExceptionDescribe();
}
jvm->DestroyJavaVM();
}void vShowError(string sError) {
MessageBox(NULL, sError.c_str(), "错误", MB_OK);
}/* 在对话框中显示错误信息,括号内包含
的GetLastError错误信息 */
void vShowLastError(string sLocalError) {
LPVOID lpSystemMsgBuf;
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpSystemMsgBuf, 0, NULL );
string sSystemError = string((LPTSTR)lpSystemMsgBuf);
vShowError(sLocalError + " [" + sSystemError + "]");
}void vAddOption(string& sValue) {
mctOptions++;
if (mctOptions >= mctOptionCapacity) {
if (mctOptionCapacity == 0) {
mctOptionCapacity = 3;
vm_options = (JavaVMOption*)malloc(mctOptionCapacity * sizeof(JavaVMOption));
} else {
JavaVMOption *tmp;
mctOptionCapacity *= 2;
tmp = (JavaVMOption*)malloc(mctOptionCapacity * sizeof(JavaVMOption));
memcpy(tmp, vm_options, (mctOptions-1) * sizeof(JavaVMOption));
free(vm_options);
vm_options = tmp;
}
}
vm_options[mctOptions-1].optionString = (char*)sValue.c_str();
}/* 如果缓冲区是"c:\app\bin\java",则把"c:\app"放入buf。*/
jboolean GetApplicationHome(char *buf, jint sz) {
char *cp;
GetModuleFileName(0, buf, sz);
*strrchr(buf, '\\') = '\0';
if ((cp = strrchr(buf, '\\')) == 0) {
// 如果应用程序放在驱动器的根目录下,且不存在bin目录
// 会出现这种情形
buf[0] = '\0';
return JNI_FALSE;
}
return JNI_TRUE;
}
运行时说找不到要启动的类,高手帮忙看一下,谢谢!
#include <jni.h>
#include <string>
using namespace std;void vShowError(string sErrorMessage);
void vShowLastError(string sErrorMessage);
void vDestroyVM(JNIEnv *env, JavaVM *jvm);
void vAddOption(string& sName);JavaVMOption* vm_options;
int mctOptions = 0;
int mctOptionCapacity = 0;
boolean GetApplicationHome(char *buf, jint sz);
typedef jint (CALLBACK *CreateJavaVM)(JavaVM **pvm, JNIEnv **penv, void *args);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){
JNIEnv *env;
JavaVM *jvm;
jint jintVMStartupReturnValue;
jclass jclassStartup;
jmethodID midStartup; // 确定各种文件所在的路径
// -应用的主目录
char home[2000];
if (!GetApplicationHome(home, sizeof(home))) {
vShowError("不能确定应用的主目录。");
return 0;
}
string sAppHome(home);
sAppHome="C:\\j2sdk1.4.2_03";
string sOption_AppHome = "-Dapplication.home=" + sAppHome;
string sJREPath = sAppHome + "\\jre";
// -VM路径
string sRuntimePath = sJREPath + "\\bin\\server\\";
string sJVMpath = sRuntimePath + "jvm.dll";
// -启动路径
string sBootPath = sJREPath + "\\lib";
string sOption_BootPath = "-Dsun.boot.class.path=" + sBootPath;
// -CLASSPATH
// string sClassPath = sAppHome + "\\classes";
string sClassPath = "C:\\CuCommonNote";
string sOption_ClassPath = "-Djava.class.path=" + sClassPath;
// 设置VM参数
// vAddOption(string("-cp ./;./lib/log4j-1.2.8.jar"));
vAddOption(sOption_ClassPath);
vAddOption(sOption_AppHome);
// VM初始化参数
JavaVMInitArgs vm_args;
vm_args.version = 0x00010002;
vm_args.options = vm_options;
vm_args.nOptions = mctOptions;
vm_args.ignoreUnrecognized = JNI_TRUE;
// 装入JVM库
HINSTANCE hJVM = LoadLibrary(sJVMpath.c_str());
if( hJVM == NULL ){
vShowLastError("不能从下面的路径装入JVM:" + sJVMpath);
return 0;
}
// 启动1.2/3/4 VM
CreateJavaVM lpfnCreateJavaVM = (CreateJavaVM) GetProcAddress(hJVM, "JNI_CreateJavaVM");
jintVMStartupReturnValue = (*lpfnCreateJavaVM) (&jvm, &env, &vm_args);
// 是否成功?
if (jintVMStartupReturnValue < 0) {
string sErrorMessage = "创建VM失败。";
vShowError(sErrorMessage);
vDestroyVM(env, jvm);
return 0;
}
// 要启动的类
string sStartupClass = "CuCommonNote/CuCommonNote";
// 注意句点符号已经被转换成斜杠
jclassStartup = env->FindClass(sStartupClass.c_str());
if (jclassStartup == NULL) {
string sErrorMessage ="找不到启动类[" +sStartupClass + "]";
vShowError(sErrorMessage);
vDestroyVM(env, jvm);
return 0;
}
// 要启动的方法
string sStartupMethod_Identifier = "main";
string sStartupMethod_TypeDescriptor ="([Ljava/lang/String;)V";
midStartup = env->GetStaticMethodID(jclassStartup,
sStartupMethod_Identifier.c_str(),
sStartupMethod_TypeDescriptor.c_str());
if (midStartup == NULL) {
string sErrorMessage = "找不到启动方法["+ sStartupClass + "."+ sStartupMethod_Identifier
+ "],类型描述符是[" + sStartupMethod_TypeDescriptor + "]";
vShowError(sErrorMessage);
vDestroyVM(env, jvm);
return 0;
}
// 构造启动方法的参数
jstring jstringExampleArg;
jclass jclassString;
jobjectArray jobjectArray_args;
jstringExampleArg = env->NewStringUTF("string1");
if (jstringExampleArg == NULL){
vDestroyVM(env, jvm);
return 0;
}
jclassString = env->FindClass("java/lang/String");
jobjectArray_args = env->NewObjectArray(1, jclassString, jstringExampleArg);
if (jobjectArray_args == NULL){
vDestroyVM(env, jvm);
return 0;
}
// 调用启动方法启动Java程序
env->CallStaticVoidMethod(jclassStartup, midStartup, jobjectArray_args);
// 在退出之前尝试分离主线程
if (jvm->DetachCurrentThread() != 0) {
vShowError("分离主线程失败。\n");
}
// 只要还有非守护线程,下面的调用将一直被挂起
jvm->DestroyJavaVM();
return 0;
}
void vDestroyVM(JNIEnv *env, JavaVM *jvm){
if (env->ExceptionOccurred()) {
env->ExceptionDescribe();
}
jvm->DestroyJavaVM();
}void vShowError(string sError) {
MessageBox(NULL, sError.c_str(), "错误", MB_OK);
}/* 在对话框中显示错误信息,括号内包含
的GetLastError错误信息 */
void vShowLastError(string sLocalError) {
LPVOID lpSystemMsgBuf;
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpSystemMsgBuf, 0, NULL );
string sSystemError = string((LPTSTR)lpSystemMsgBuf);
vShowError(sLocalError + " [" + sSystemError + "]");
}void vAddOption(string& sValue) {
mctOptions++;
if (mctOptions >= mctOptionCapacity) {
if (mctOptionCapacity == 0) {
mctOptionCapacity = 3;
vm_options = (JavaVMOption*)malloc(mctOptionCapacity * sizeof(JavaVMOption));
} else {
JavaVMOption *tmp;
mctOptionCapacity *= 2;
tmp = (JavaVMOption*)malloc(mctOptionCapacity * sizeof(JavaVMOption));
memcpy(tmp, vm_options, (mctOptions-1) * sizeof(JavaVMOption));
free(vm_options);
vm_options = tmp;
}
}
vm_options[mctOptions-1].optionString = (char*)sValue.c_str();
}/* 如果缓冲区是"c:\app\bin\java",则把"c:\app"放入buf。*/
jboolean GetApplicationHome(char *buf, jint sz) {
char *cp;
GetModuleFileName(0, buf, sz);
*strrchr(buf, '\\') = '\0';
if ((cp = strrchr(buf, '\\')) == 0) {
// 如果应用程序放在驱动器的根目录下,且不存在bin目录
// 会出现这种情形
buf[0] = '\0';
return JNI_FALSE;
}
return JNI_TRUE;
}
运行时说找不到要启动的类,高手帮忙看一下,谢谢!
解决方案 »
- MFC单文档实现打印的问题,急,求助!
- 怎么样捕捉在edit control中按下回车键这一事件?
- loadIcon 问题
- 请问哪里还有潘爱民老师翻译的|《VC++技术内幕》第四版下载
- ===> 做了个 UDP Server,怎么对其做压力测试?
- 如何实现文件夹/文件选择对话框,就像 Visual Studio.net 中的那样?
- 再次请教重叠IO模型的问题
- 用c++实现判断视频画面变化
- 请教:在广域网中使用winsock传输大型文件该用什么协议?谢谢
- 找配套光盘.....
- HOOKDLL注入Explorer.exe后在Explorer进程中安装钩子的问题
- 那位朋友有做hlp的文档。。。。高分求购
把java的那些路径设置为系统路径
我的sdk1装在C:\j2sdk1.4.2_03
应该没问题的。。