#include <windows.h> #include <jni.h>
//#pragma comment( linker, "/subsystem:"console" /entry:"mainCRTStartup"" )
#pragma
comment( linker, "/subsystem:"windows" /entry:"WinMainCRTStartup"" )
typedef jint (JNICALL *JNICREATEPROC)(JavaVM **,
void
**,
void
*);
bool
setStream(JNIEnv *env,
const
char
* pszFileName,
const
char
* pszMethod);
//
启动
java
虚拟机方法
//bool main(int argc,char *argv[])
int
WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInstance,PSTR szCmdLine,
int
iCmdShow)
...
{
//jvm
动态库的路径
const
char
szJvmPath[] = "d:/jdk1.5.0_07/jre/bin/server/jvm.dll";
//java
虚拟机的启动参数,每个参数写一项,不能合在一起写
int
nOptionCount = 2; JavaVMOption options[2]; options[1].optionString = "-Xmx256M";
//
设置
classpath
options[0].optionString = "-Djava.class.path=./Test.exe"; JavaVMInitArgs vm_args; vm_args.version = JNI_VERSION_1_4; vm_args.options = options; vm_args.nOptions = nOptionCount; vm_args.ignoreUnrecognized = JNI_TRUE;
//
启动类
,
注意分割符是
/
,例如启动类
test.JTest
应该写成
test/JTest
const
char
szStartClass[] = "com/primeton/test/TestClass";
//
启动方法,通常是
main
函数,你也可以设定成其他函数
const
char
szStartMethod[] = "main";
//
重导向文件
const
char
szStdoutFileName[] = "stdout.txt";
const
char
szStderrFileName[] = "stderr.txt";
//java
程序的命令行参数
int
nParamCount = 2;
const
char
*szParams[2] =
...
{"arg1","arg2"};
//
加载
JVM
。
HINSTANCE jvmDll = LoadLibrary(szJvmPath);
if
(jvmDll == NULL)
...
{ printf("
加载
JVM
动态库错误。
%l", ::GetLastError());
return
false
; }
//
查找
JNI_CreateJavaVM
过程。
JNICREATEPROC jvmCreateProc = (JNICREATEPROC)GetProcAddress(jvmDll, "JNI_CreateJavaVM");
if
(jvmCreateProc == NULL)
...
{ FreeLibrary(jvmDll); printf("
查找
JNI_CreateJavaVM
过程错误。
%l", ::GetLastError());
return
false
; }
//
创建
JVM
。
JNIEnv *env; JavaVM *jvm; jint r = (jvmCreateProc)(&jvm, (
void
**)&env, &vm_args);
if
(r < 0 || jvm == NULL || env == NULL)
...
{ FreeLibrary(jvmDll); printf( "
创建
JVM
发生错误。
");
return
false
; }
//
重导向
stdout, stderr
到输出文件
if
(!setStream(env, szStdoutFileName, "setOut"))
...
{ printf("
设置
stdout
输出文件失败
");
return
false
; }
if
(!setStream(env, szStderrFileName, "setErr"))
...
{ printf("
设置
stderr
输出文件失败
");
return
false
; }
//
加载启动类。
jclass serviceClass = env->FindClass(szStartClass);
if
(env->ExceptionCheck() == JNI_TRUE || serviceClass == NULL)
...
{ env->ExceptionDescribe(); env->ExceptionClear(); FreeLibrary(jvmDll); printf("
加载启动类失败。
");
return
false
; }
//
启动方法
jmethodID mid = env->GetStaticMethodID(serviceClass, szStartMethod , "([Ljava/lang/String;)V");
if
(env->ExceptionCheck() == JNI_TRUE || mid == NULL)
...
{ env->ExceptionDescribe(); env->ExceptionClear(); FreeLibrary(jvmDll); printf("
查找启动方法失败。
");
return
false
; }
//
查找
String
类。
jclass stringClass = env->FindClass("java/lang/String");
if
(env->ExceptionCheck() == JNI_TRUE || stringClass == NULL)
...
{ env->ExceptionDescribe(); env->ExceptionClear(); FreeLibrary(jvmDll); printf("
查找
String
类失败。
");
return
false
; } jstring jstr; jobjectArray args = 0; args = env->NewObjectArray(2, stringClass, 0);
for
(
int
i=0; i<nParamCount; i++)
...
{ jstr = env->NewStringUTF(szParams[i]);
if
(jstr == 0)
...
{ printf("
分配
String
失败
");
if
(env->ExceptionOccurred())
...
{ env->ExceptionDescribe(); env->ExceptionClear(); }
return
false
; } env->SetObjectArrayElement(args, i, jstr);
if
(env->ExceptionCheck() == JNI_TRUE)
...
{ printf("
设置参数失败
");
if
(env->ExceptionOccurred())
...
{ env->ExceptionDescribe(); env->ExceptionClear(); }
return
false
; } }
//
调用启动类的启动方法启动
Java
程序
//env->CallStaticVoidMethod(serviceClass, mid, parameterArray);
env->CallStaticVoidMethod(serviceClass, mid, args);
if
(env->ExceptionCheck() == JNI_TRUE)
...
{ env->ExceptionDescribe(); env->ExceptionClear(); FreeLibrary(jvmDll);
return
false
; } MSG msg ;
while
(GetMessage (&msg, NULL, 0, 0))
...
{ TranslateMessage (&msg) ; DispatchMessage (&msg) ; }
return
true
; }
//
设置输出流的方法
bool
setStream(JNIEnv *env,
const
char
* pszFileName,
const
char
* pszMethod)
...
{
int
pBufferSize = 1024;
char
* pBuffer =
new
char
[pBufferSize];
//
创建字符串对象。
jstring pathString = env->NewStringUTF(pszFileName);
if
(env->ExceptionCheck() == JNI_TRUE || pathString == NULL)
...
{ env->ExceptionDescribe(); env->ExceptionClear(); printf("
创建字符串失败。
");
return
false
; }
//
查找
FileOutputStream
类。
jclass fileOutputStreamClass = env->FindClass("java/io/FileOutputStream");
if
(env->ExceptionCheck() == JNI_TRUE || fileOutputStreamClass == NULL)
...
{ env->ExceptionDescribe(); env->ExceptionClear(); printf("
查找
FileOutputStream
类失败。
");
return
false
; }
//
查找
FileOutputStream
类构造方法。
jmethodID fileOutputStreamConstructor = env->GetMethodID(fileOutputStreamClass, "<init>", "(Ljava/lang/String;)V");
if
(env->ExceptionCheck() == JNI_TRUE || fileOutputStreamConstructor == NULL)
...
{ env->ExceptionDescribe(); env->ExceptionClear(); printf("
查找
FileOutputStream
类构造方法失败。
");
return
false
; }
//
创建
FileOutputStream
类的对象。
jobject fileOutputStream = env->NewObject(fileOutputStreamClass, fileOutputStreamConstructor, pathString);
if
(env->ExceptionCheck() == JNI_TRUE || fileOutputStream == NULL)
...
{ env->ExceptionDescribe(); env->ExceptionClear(); printf("
创建
FileOutputStream
类的对象失败。
");
return
false
; }
//
查找
PrintStream
类。
jclass printStreamClass = env->FindClass("java/io/PrintStream");
if
(env->ExceptionCheck() == JNI_TRUE || printStreamClass == NULL)
...
{ env->ExceptionDescribe(); env->ExceptionClear(); printf("
查找
PrintStream
类失败。
");
return
false
; }
//
查找
PrintStream
类构造方法。
jmethodID printStreamConstructor = env->GetMethodID(printStreamClass, "<init>", "(Ljava/io/OutputStream;)V");
if
(env->ExceptionCheck() == JNI_TRUE || printStreamConstructor == NULL)
...
{ env->ExceptionDescribe(); env->ExceptionClear(); printf("
查找
PrintStream
类构造方法失败。
");
return
false
; }
//
创建
PrintStream
类的对象。
jobject printStream = env->NewObject(printStreamClass, printStreamConstructor, fileOutputStream);
if
(env->ExceptionCheck() == JNI_TRUE || printStream == NULL)
...
{ env->ExceptionDescribe(); env->ExceptionClear(); printf("
创建
PrintStream
类的对象失败。
");
return
false
; }
//
查找
System
类。
jclass systemClass = env->FindClass("java/lang/System");
if
(env->ExceptionCheck() == JNI_TRUE || systemClass == NULL)
...
{ env->ExceptionDescribe(); env->ExceptionClear(); printf( "
查找
System
类失败。
");
return
false
; }
//
查找
System
类设置方法。
jmethodID setStreamMethod = env->GetStaticMethodID(systemClass, pszMethod, "(Ljava/io/PrintStream;)V");
if
(env->ExceptionCheck() == JNI_TRUE || setStreamMethod == NULL)
...
{ env->ExceptionDescribe(); env->ExceptionClear(); printf("
查找
System
类设置方法失败。
");
return
false
; }
//
设置
System
类的流。
env->CallStaticVoidMethod(systemClass, setStreamMethod, printStream);
if
(env->ExceptionCheck() == JNI_TRUE)
...
{ env->ExceptionDescribe(); env->ExceptionClear(); printf("
设置
System
类的流失败。
");
return
false
; }
return
true
; }
|