T
tony_lincoln
Dear friends,
I am using JNI to call java from C++. I use j2sdk1.4.1 and Visual C++
6.
Parameter setting in Visual C++ 6:
In Tools¡úOptions->Include Files:
1. C:\j2sdk1.4.1_02\include
2. C:\j2sdk1.4.1_02\include\win32
In Tools->Options->Library Files:
C:\j2sdk1.4.1_02\lib
set Path = C:\j2sdk1.4.1_02\jre\bin\client
All of these settings are correct. When I compiled the invoke.cpp, no
errors. But when I execute it, DOS concole window popped up and one
sentence appeared:
"Sorry, I can't find the class. Press any key to continue"
The "Sorry, I can't find the class" came from my invoke.cpp. This
means, this cpp can not find my java class, even when I put the java
class "Demo" into the same subdir as invoke.cpp. Where should I put the
Demo class?
Any hints? Thanks a lot!
The related codes(Demo.java, invoke.cpp) are enclosed here:
//Demo.java
************************************************
package jni.test;
public class Demo {
public static int COUNT = 8;
public String msg;
private int[] counts;
public Demo() {
this("ȱʡ¹¹Ô캯Êý");
}
public Demo(String msg) {
System.out.println("<init>:" + msg);
this.msg = msg;
this.counts = null;
}
public String getMessage() {
return msg;
}
public int[] getCounts(){
return counts;
}
public void setCounts(int[] counts){
this.counts = counts;
}
public void throwExcp()
throws IllegalAccessException{
throw new IllegalAccessException
("exception occur.");
}
}// end class Demo.
*****************************************************************+
The c++ code is the following:
// invoke.cpp
********************************************************************
/*for C++,debugged with Visual C++ 6.0*/
#ifndef __cplusplus
#define __cplusplus
#endif
#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#pragma comment (lib,"C:\\j2sdk1.4.1_02\\lib\\jvm.lib")
int JStringToChar(JNIEnv *env, jstring str, LPTSTR desc, int desc_len)
{
int len = 0;
if(desc==NULL||str==NULL)
return -1;
wchar_t *w_buffer = new wchar_t[1024];
ZeroMemory(w_buffer,1024*sizeof(wchar_t));
wcscpy(w_buffer,env->GetStringChars(str,0));
env->ReleaseStringChars(str,w_buffer);
ZeroMemory(desc,desc_len);
len =
WideCharToMultiByte(CP_ACP,0,w_buffer,1024,desc,desc_len,NULL,NULL);
if(len>0 && len<desc_len) desc[len]=0;
delete[] w_buffer;
return strlen(desc);
}
jstring NewJString(JNIEnv* env,LPTSTR str)
{
if(!env || !str) return 0;
int slen = strlen(str);
jchar* buffer = new jchar[slen];
int len = MultiByteToWideChar(CP_ACP,0,str,strlen(str),buffer,slen);
if(len>0 && len < slen) buffer[len]=0;
jstring js = env->NewString(buffer,len);
delete [] buffer;
return js;
}
void main() {
JavaVM *jvm;
JNIEnv *env;
JavaVMInitArgs vm_args;
JavaVMOption options[3];
options[0].optionString = "-Djava.compiler=NONE";
options[1].optionString = "-Djava.classpath=.";
options[2].optionString = "";
vm_args.version = JNI_VERSION_1_4;
vm_args.nOptions = 3;
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_TRUE;
jint res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
if (res < 0) {
fprintf(stderr, "Can't create Java VM\n");
exit(1);
};
jclass cls = env->FindClass("Demo");
if (cls == 0) printf("Sorry, I can't find the class");
jmethodID get_main_id =
env->GetStaticMethodID(cls,"main","([Ljava/lang/StringV");
jclass string = env->FindClass("java/lang/String");
jobjectArray args = env->NewObjectArray(0,string, NULL);
env->CallStaticVoidMethod(cls,get_main_id,args);
jvm->DestroyJavaVM();
fprintf(stdout, "Java VM destory\n");
}//end main.
***********************************************************************
//end of invoke.cpp
I am using JNI to call java from C++. I use j2sdk1.4.1 and Visual C++
6.
Parameter setting in Visual C++ 6:
In Tools¡úOptions->Include Files:
1. C:\j2sdk1.4.1_02\include
2. C:\j2sdk1.4.1_02\include\win32
In Tools->Options->Library Files:
C:\j2sdk1.4.1_02\lib
set Path = C:\j2sdk1.4.1_02\jre\bin\client
All of these settings are correct. When I compiled the invoke.cpp, no
errors. But when I execute it, DOS concole window popped up and one
sentence appeared:
"Sorry, I can't find the class. Press any key to continue"
The "Sorry, I can't find the class" came from my invoke.cpp. This
means, this cpp can not find my java class, even when I put the java
class "Demo" into the same subdir as invoke.cpp. Where should I put the
Demo class?
Any hints? Thanks a lot!
The related codes(Demo.java, invoke.cpp) are enclosed here:
//Demo.java
************************************************
package jni.test;
public class Demo {
public static int COUNT = 8;
public String msg;
private int[] counts;
public Demo() {
this("ȱʡ¹¹Ô캯Êý");
}
public Demo(String msg) {
System.out.println("<init>:" + msg);
this.msg = msg;
this.counts = null;
}
public String getMessage() {
return msg;
}
public int[] getCounts(){
return counts;
}
public void setCounts(int[] counts){
this.counts = counts;
}
public void throwExcp()
throws IllegalAccessException{
throw new IllegalAccessException
("exception occur.");
}
}// end class Demo.
*****************************************************************+
The c++ code is the following:
// invoke.cpp
********************************************************************
/*for C++,debugged with Visual C++ 6.0*/
#ifndef __cplusplus
#define __cplusplus
#endif
#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#pragma comment (lib,"C:\\j2sdk1.4.1_02\\lib\\jvm.lib")
int JStringToChar(JNIEnv *env, jstring str, LPTSTR desc, int desc_len)
{
int len = 0;
if(desc==NULL||str==NULL)
return -1;
wchar_t *w_buffer = new wchar_t[1024];
ZeroMemory(w_buffer,1024*sizeof(wchar_t));
wcscpy(w_buffer,env->GetStringChars(str,0));
env->ReleaseStringChars(str,w_buffer);
ZeroMemory(desc,desc_len);
len =
WideCharToMultiByte(CP_ACP,0,w_buffer,1024,desc,desc_len,NULL,NULL);
if(len>0 && len<desc_len) desc[len]=0;
delete[] w_buffer;
return strlen(desc);
}
jstring NewJString(JNIEnv* env,LPTSTR str)
{
if(!env || !str) return 0;
int slen = strlen(str);
jchar* buffer = new jchar[slen];
int len = MultiByteToWideChar(CP_ACP,0,str,strlen(str),buffer,slen);
if(len>0 && len < slen) buffer[len]=0;
jstring js = env->NewString(buffer,len);
delete [] buffer;
return js;
}
void main() {
JavaVM *jvm;
JNIEnv *env;
JavaVMInitArgs vm_args;
JavaVMOption options[3];
options[0].optionString = "-Djava.compiler=NONE";
options[1].optionString = "-Djava.classpath=.";
options[2].optionString = "";
vm_args.version = JNI_VERSION_1_4;
vm_args.nOptions = 3;
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_TRUE;
jint res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
if (res < 0) {
fprintf(stderr, "Can't create Java VM\n");
exit(1);
};
jclass cls = env->FindClass("Demo");
if (cls == 0) printf("Sorry, I can't find the class");
jmethodID get_main_id =
env->GetStaticMethodID(cls,"main","([Ljava/lang/StringV");
jclass string = env->FindClass("java/lang/String");
jobjectArray args = env->NewObjectArray(0,string, NULL);
env->CallStaticVoidMethod(cls,get_main_id,args);
jvm->DestroyJavaVM();
fprintf(stdout, "Java VM destory\n");
}//end main.
***********************************************************************
//end of invoke.cpp