The Artima Developer Community
Sponsored Link

Java Answers Forum
visual c++ and JNI

10 replies on 1 page. Most recent reply: Oct 6, 2003 8:29 PM by Joe Parks

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 10 replies on 1 page
Agung Wibowo

Posts: 3
Nickname: jdeveloper
Registered: Oct, 2003

visual c++ and JNI Posted: Oct 1, 2003 2:17 AM
Reply to this message Reply
Advertisement
is there any info about using jni from visual c++ especially

application with graphical user interface to use jni function. I succeeds to use console application to use jni function to call function in java class, but the problem occurred when i changed the code into gui based. The difficulties are some functions cannot be used or called not like in console App, especially the number of parameter needed for function declaration is not matched. So the problem arised from using jni in visual c++ rather than using jni in java programming. Many examples discuss using jni to call java function but to use jni function both in callback function or dll by using visual c++ itself is very rare (gui based) because of the different declaration of jni function to be used from visual c++ and some initialization like JNIENV object to be used as actual parameter is very difficult. So JNI as if to be new programming language not as an proxy for visual c++ as an example. Or may be some information is hidden and rare to be exposed.


Joe Parks

Posts: 107
Nickname: joeparks
Registered: Aug, 2003

Re: visual c++ and JNI Posted: Oct 1, 2003 2:12 PM
Reply to this message Reply
I've never actually initiated a call from native code into java via JNI; it's always been the opposite direction.

Are you doing something similar to:
http://java.sun.com/docs/books/tutorial/native1.1/invoking/example-1dot1/invoke.c ?

I know that you don't want to use a console application, but is the direction you were heading in? I'll see if I can get this working later, and then move on to a GUI application doing the same thing.

Agung Wibowo

Posts: 3
Nickname: jdeveloper
Registered: Oct, 2003

Re: visual c++ and JNI Posted: Oct 1, 2003 7:25 PM
Reply to this message Reply
Thank's for your response but looks this code

i create java class : LoadPicture

and successfully run this program as a replacement of
java intepreter to run LoadPicture class.

Next i want to convert this console application into
gui win32 application.

i guess just copy the working routine inside main function
into callback function behind Button after included "jni.h"
but the problem is always arised to functions in jni cannot
be recognized by visual c++ itself or function declaration that working properly in console app to be not matched. i don't know if i am wrong in making header configuration setting but i have checked it.

The difficulties from visual c++ are :

how can we initialize JNIEnv *env;

as an actual parameter for function in JNI with declaration resulted from javah -jni our java class command, because to do something in visual c++ to use jni we must use this object before using another jni function. From example i have learnt it automatically used inside main function but in callback function we got problem to refer this object.

your helping will be appreciated.


// run on jdk 1.4
// usage invoke jvm javaclassname
// Adding Path reference to jvm.dll in jre\bin\client or jre\bin\server directory

#include "jni.h"
#include <windows.h>

#ifdef _WIN32
#define PATH_SEPARATOR ';'
#else
/* UNIX */
#define PATH_SEPARATOR ':'
#endif
#define USER_CLASSPATH "."
/* where Prog.class is */


typedef jint (*P_JNI_GetDefaultJavaVMInitArgs)(void *args);
typedef jint (*P_JNI_CreateJavaVM)(JavaVM **pvm, JNIEnv ** penv, void *args);


main(int argc,char** argv)
{
JNIEnv *env;
JavaVM *jvm;
// JDK1_1InitArgs vm_args;
JavaVMInitArgs vm_args; // jdk 1.2
jint res;
jclass cls;
jmethodID mid;
jstring jstr;
jobjectArray args;
char classpath[1024];
HANDLE hLib = NULL;


/* Pointer to required functions */
P_JNI_GetDefaultJavaVMInitArgs pfnGetDefaultJavaVMInitArgs = NULL;
P_JNI_CreateJavaVM pfnCreateJavaVM = NULL;



/* Load the library */
// printf("Loading Library .... <%s>\n",argv[1]);
hLib = LoadLibrary("jvm");

if(hLib == NULL)
{
printf("Unable to Load Library.... exitting....");
exit(-1);
}


/* IMPORTANT: specify vm_args version # if you use JDK1.1.2 and beyond */
//vm_args.version = 0x00010001;
vm_args.version = JNI_VERSION_1_2;
vm_args.nOptions = 0;
vm_args.ignoreUnrecognized = TRUE;

/* Create the Java VM */

/* Store the function pointer for creating the VM */
pfnCreateJavaVM = (P_JNI_CreateJavaVM) GetProcAddress(hLib, "JNI_CreateJavaVM");

/* Create the Java VM */
if(pfnCreateJavaVM != NULL)
res = (*pfnCreateJavaVM)(&jvm,&env,&vm_args);

if (res < 0)
{
fprintf(stderr, "Can't create Java VM\n");
exit(1);
}
else
{
// printf("Java Virtual Machine created !");

}

cls = (*env)->FindClass(env, "LoadPicture");
if (cls == 0)
{
fprintf(stderr, "Can't find Prog class\n");
exit(1);
}


mid = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V");
if (mid == 0)
{
fprintf(stderr, "Can't find Prog.main\n");
exit(1);
}


jstr = (*env)->NewStringUTF(env, " from C!");

if (jstr == 0)
{
fprintf(stderr, "Out of memory\n");
exit(1);
}


args = (*env)->NewObjectArray(env, 1, (*env)->FindClass(env, "java/lang/String"), jstr);
if (args == 0)
{
fprintf(stderr, "Out of memory\n");
exit(1);
}


(*env)->CallStaticVoidMethod(env, cls, mid, args);


}

Joe Parks

Posts: 107
Nickname: joeparks
Registered: Aug, 2003

Re: visual c++ and JNI Posted: Oct 2, 2003 5:18 AM
Reply to this message Reply
I still haven't tried this yet, but in the code on java.sun.com above, the following (sort of) is used:
    JNIEnv *env;
    JavaVM *jvm;
    JDK1_1InitArgs vm_args;
    jint resultCode;
 
 
    // Use the appropriate version (defined in jni.h)
    vm_args.version = 0x00010001;
 
 
    JNI_GetDefaultJavaVMInitArgs(&vm_args);
    resultCode = JNI_CreateJavaVM(&jvm,&env,&vm_args);
    if (res < 0) {
        fprintf(stderr, "Can't create Java VM\n");
        exit(1);
    }
 
 
    // env is now initialized
 

Joe Parks

Posts: 107
Nickname: joeparks
Registered: Aug, 2003

Re: visual c++ and JNI Posted: Oct 2, 2003 5:22 AM
Reply to this message Reply
Perhaps make env a global variable?

Joe Parks

Posts: 107
Nickname: joeparks
Registered: Aug, 2003

Re: visual c++ and JNI Posted: Oct 2, 2003 10:09 AM
Reply to this message Reply
I still can't get it to work from a console application.

I am able to create the JVM, but I can't get it to load a class. Here's the code that I'm using
#include "stdafx.h"
 
int _tmain(int argc, _TCHAR* argv[])
{
	JNIEnv *env;
	JavaVM *jvm;
	JavaVMInitArgs vm_args;
	JavaVMOption vmOptions[1];
	jint resultCode;
	jclass clazz;
 
	// Use the appropriate version (defined in jni.h)
	vm_args.version = JNI_VERSION_1_4;
	vmOptions[0].optionString = ".";
	vm_args.options = vmOptions;
	vm_args.nOptions = 1;
	vm_args.ignoreUnrecognized = JNI_TRUE;
 
	resultCode = JNI_CreateJavaVM(&jvm, reinterpret_cast<void**>(&env), &vm_args);
	if (resultCode < 0) 
	{
		std::cerr << "Can't create Java VM" << std::endl;
		exit(1);
	}
	// env is now initialized
	std::cout << "It is initialized!" << std::endl;
	clazz = env->FindClass("joe.TestApplication");
	if (clazz == 0)
	{
		std::cerr << "Unable to load class." << std::endl;
	}
	else
	{
		std::cout << "The class is loaded!" << std::endl;
	}
	return 0;
}

And here's the output:

It is initialized!
Unable to load class.

Joe Parks

Posts: 107
Nickname: joeparks
Registered: Aug, 2003

Re: visual c++ and JNI Posted: Oct 2, 2003 10:15 AM
Reply to this message Reply
It figures that as soon as I post something, I find the problem.

The class name passed to FindClass() is separated by slashes, not periods:
	clazz = env->FindClass("joe/TestApplication");

Joe Parks

Posts: 107
Nickname: joeparks
Registered: Aug, 2003

Re: visual c++ and JNI Posted: Oct 2, 2003 11:30 AM
Reply to this message Reply
I was able to drop the code into a GUI application and invoke it.
The only issue that I had was the CLASSPATH. I still haven't figured out how to set the classpath programmatically (the vm_args.options apparently has no effect). I had to include "." in the system CLASSPATH, and put the class files/package structure in the working directory of the Visual C++ project.

Agung Wibowo

Posts: 3
Nickname: jdeveloper
Registered: Oct, 2003

Re: visual c++ and JNI Posted: Oct 2, 2003 7:56 PM
Reply to this message Reply
the problem is JNI cannot be used in visual c++ with cpp as an extension for example i try to modify create dll by using
c style and compile it in command line than using visual c++ editor it constiutes that some functions and variables working in compile time but there is still problem to remove export declarations like extern "C" decl export.

Because function that is exist in dll must cooperates with user of the function both from visual c++ side or java side,
we are still confuse especially to make compile time successfully in visual c++ editor to create gui base.

For temporary solution we must use Memory mapping as medium to transfer data from visual c++, DLL contains jni routine and java itself.

The difficulties are still remain to create java virtual machine from dll as mediary. I have tried but got hung, maybe so much process getting involved in loading process.

first from visual c++ app must load dll contained jni routine, second dll itself must load JVM.dll as an gate to enter java environment. we are still tyring.

any response and solution will be proudly accepted :->

Joe Parks

Posts: 107
Nickname: joeparks
Registered: Aug, 2003

Re: visual c++ and JNI Posted: Oct 3, 2003 4:15 AM
Reply to this message Reply
I don't understand.

I think that I did exactly what you are talking about, although I still haven't been able to set the classpath from within c++.

Is <JRE_HOME>/bin/client|server/jvm.dll in your path?
Does your VC++ project link against <JRE_HOME>/lib/jvm.lib?
Are <JDK_HOME>/include and <JDK_HOME>/include/win32 in your VC++ include path?

What version of Visual C++ are you using?
Which JDK?

Would you be willing to send the files that you're working with?

What exists in Java, by the way, that you can't do in C++?

Joe Parks

Posts: 107
Nickname: joeparks
Registered: Aug, 2003

Re: visual c++ and JNI Posted: Oct 6, 2003 8:29 PM
Reply to this message Reply
> Is <JRE_HOME>/bin/client|server/jvm.dll in your path?
> Does your VC++ project link against
> <JRE_HOME>/lib/jvm.lib?
> Are <JDK_HOME>/include and <JDK_HOME>/include/win32 in
> your VC++ include path?


Did this help you at all?

Flat View: This topic has 10 replies on 1 page
Topic: Java jar file Previous Topic   Next Topic Topic: code required for nested for loops

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use